Make WordPress Core

Opened 6 weeks ago

Closed 5 weeks ago

#64403 closed defect (bug) (fixed)

wp-auth-check.min.js: TypeError: h is undefined

Reported by: artz91's profile ArtZ91 Owned by: westonruter's profile westonruter
Milestone: 7.0 Priority: normal
Severity: normal Version: 3.6
Component: General Keywords: has-patch
Focuses: javascript, administration Cc:

Description

This error was catched automatically by error handler logger in admin area:

Type: Standard JS Error
Message: TypeError: h is undefined
File: /wp-includes/js/wp-auth-check.min.js
Line: 2, Col: 652
User role: Editor
WP Version: 6.9

...||d?a["wp-auth-check"]&&!h.hasClass("hidden")&&r():...
............................↑............................

I think it's means that the wrap variable is undefined by some reason inside heartbeat-tick.wp-auth-check event handler.

Change History (9)

#1 @westonruter
6 weeks ago

  • Keywords reporter-feedback added

@ArtZ91 Can you enable SCRIPT_DEBUG to verify that?

If so, then somehow this line is failing:

wrap = $( '#wp-auth-check-wrap' );

Does your admin page have an element with a wp-auth-check-wrap ID?

Even if it does, jQuery should be populating wrap with an empty jQuery object. It shouldn't result in an error. For example:

jQuery('#this-does-not-exist').hasClass('nope');

This returns false in the console; it doesn't throw an error.

#2 @ArtZ91
5 weeks ago

  • Resolution set to maybelater
  • Status changed from new to closed

The problem has not recurred. Note: the bug was detected not in my account, it's Editor's account and the Editor user can't confirm this issue influenced him.

I setup the SCRIPT_DEBUG constant for further logging.

#3 @westonruter
5 weeks ago

  • Milestone Awaiting Review deleted
  • Resolution changed from maybelater to worksforme

#4 @siliconforks
5 weeks ago

Here's a (somewhat contrived) way to trigger this:

  1. Open the file wp-includes/js/heartbeat.js and look for the anonymous function with the comment Start one tick after DOM ready.
  1. Modify the function so it looks like this:
// Start one tick after DOM ready.
$( function() {
	settings.lastTick = time();
	scheduleNextTick();

	/*
	Sleep for 2 seconds.  That should be enough for an AJAX round-trip to occur.
	*/
	let startTime = Date.now();
	while ( Date.now() - startTime < 2000 ) {
		// do nothing
	}
});
  1. Make sure you have SCRIPT_DEBUG set to true.
  1. Now in Firefox (I couldn't get this to work in Chrome for some reason) log in to the admin section and click "Posts".
  1. In your browser console, you should see the error:
Uncaught TypeError: can't access property "hasClass", wrap is undefined

#5 @westonruter
5 weeks ago

  • Keywords needs-patch added; reporter-feedback removed
  • Milestone set to 7.0
  • Resolution worksforme deleted
  • Status changed from closed to reopened
  • Version set to 3.6

OK, I'm able to reproduce the issue, although not with the patch in 4.

This plugin re-creates the scenario:

<?php
/**
 * Plugin Name: Try Early Heartbeat Tick
 */

add_action(
        'admin_enqueue_scripts',
        static function () {
                wp_add_inline_script(
                        'wp-auth-check',
                        'jQuery( document ).trigger( "heartbeat-tick", { "wp-auth-check": false } );'
                );
        }
);

The issue is due to a race condition. The heartbeat-tick event may fire on the document before the DOMContentLoad event fires. This means that the code that sets the wrap variable may in fact run after the event handler for the heartbeat-tick event.

It looks like this was introduced a long time ago, in [23805] for #23295 with a refresh in [50547] which doesn't seem to have changed the underlying problem.

Last edited 5 weeks ago by westonruter (previous) (diff)

This ticket was mentioned in PR #10624 on WordPress/wordpress-develop by @westonruter.


5 weeks ago
#6

  • Keywords has-patch added; needs-patch removed

#7 follow-up: @westonruter
5 weeks ago

  • Owner set to westonruter
  • Status changed from reopened to accepted

@siliconforks Please give the this patch a try.

#8 in reply to: ↑ 7 @siliconforks
5 weeks ago

Replying to westonruter:

@siliconforks Please give the this patch a try.

PR #10624 does seem to fix the issue (I tested it in Firefox).

#9 @westonruter
5 weeks ago

  • Resolution set to fixed
  • Status changed from accepted to closed

In 61379:

Heartbeat: Handle race condition in wp-auth-check where heartbeat-tick may fire before DOMContentLoaded.

Developed in https://github.com/WordPress/wordpress-develop/pull/10624

Follow-up to [23805], [50547].

Props westonruter, ArtZ91, siliconforks.
See #23295.
Fixes #64403.

Note: See TracTickets for help on using tickets.