Fatal error with latest update
-
We run iControlWP and hundreds of our sites have been knocked offline since your latest update.
We get this fatal error:
Fatal error: Unknown: Cannot use output buffering in output buffering display handlers in Unknown on line 0I narrowed it down to WP Super Cache and us simply calling PHP
die()
.Can you please point to the changes/fix for this as soon as possible?
-
So the error is caused somewhere inside WP Super Cache – likely inside the shutdown callback.
In test, I can prevent the error by doing this:
global $wp_query; if ( empty( $wp_query ) ) { $wp_query = new WP_Query(); }
Because another error being flagged is:
PHP Fatal error: Call to a member function get() on null in /home/stuff/public_html/wp-includes/query.php on line 28
You’re trying to get a var before the WP Query is setup – you’re assuming that when you run the shutdown that
get_query_var()
is usable.Thanks for debugging that. What kinds of pages triggered that error? Were they feeds, or pages or posts? Or some custom post type?
I presume you added the empty() check inside wp_super_cache_query_vars() ?
We also got caught out by a bug in this plugin during our morning auto-update. We’re using multisite, and this plugin was causing 500 errors for all wordpress content, pages, posts, and even the admin areas, even the /wp-admin and /wp-login.php.
Once I network disabled it (hoorah for wp-cli ! :), I was able to log in and see the following error messages from wp-super-cache on the amdin dashboard:
Warning! WP Super Cache caching was broken but has been fixed! The script advanced-cache.php could not load wp-cache-phase1.php. The file /wordpress-data/wordpress/wp-content/advanced-cache.php has been recreated and WPCACHEHOME fixed in your wp-config.php. Reload to hide this message. Warning! Could not update /wordpress-data/wordpress/wp-config.php! WPCACHEHOME must be set in config file.
Update:
I just noticed that, although the wp-cli network disable command resurrected my wp multisite, the plugin doesn’t seem to be completely disabled. When I check in my network > plugins, wp-super-cache is still listed as network activated, and when I go to disable it, I get the following message:
Could not remove WP_CACHE define from /wordpress-data/wordpress/wp-config.php. Please edit that file and remove the line containing the text 'WP_CACHE'. Then refresh this page.
For security reasons, we don’t allow the apache user/group to edit any www files directly, which might have something to do with why this updated has failed for us (and others) so spectacularly. This isn’t an unheard of practice, so I’d suggest that, as part of the update, if possible, first check to see if you can write to the necessary files, and if not, back out of the update at that point and log an admin error message at that point with instructions on what changes are needed in those files.
- This reply was modified 7 years, 3 months ago by rslater_illinois.
My problem as following:
it will show white page for all of site of both backend and frontend.
FYI: WordPress Mu with the version:4.5.7, HHVM+Redis cache.
So, the only thing what I can do is to deactivate it.
Alex
- This reply was modified 7 years, 3 months ago by alexlii.
Thanks for debugging that. What kinds of pages triggered that error? Were they feeds, or pages or posts? Or some custom post type?
I presume you added the empty() check inside wp_super_cache_query_vars() ?
It doesn’t happen on pages necessarily, but happens at the time of the
plugins_loaded
hook.We don’t call
wp_super_cache_query_vars()
. We calldie();
and this shuts down the PHP run, and calls your callback. And your callback tries to useget_query_var()
but it can’t, becauseWP_Query
hasn’t been initialised yet. Your code assumes it’s already ready at any stage of the WP load, but it’s not. This is new code in 1.5.4 in your shutdown handler routine.It’s got nothing to do with what we’re doing. Your code assumes that the WP load is in a given state (i.e. WP Query is ready), but it’s not and we’re just triggering the bug because we terminate execution too early for you.
- This reply was modified 7 years, 3 months ago by Paul.
@paultgoodchild – thanks. The output callback calls wp_super_cache_query_vars() which is why you’re seeing this error. The vast majority of WordPress users won’t ever see this happen to them though.
Can you try the fix I created here? I put the empty() check in wp_super_cache_query_vars() before query variables are tested.
@alexlii – start a new thread please.
@rslater_illinois – good idea, but it’ll get lost here. Can you open a ticket in https://github.com/Automattic/wp-super-cache/ with your suggestion please?
I’m wondering if that is the problem/fix.
You’re calling
ob_start( 'wp_cache_ob_callback' )
. I’m concerned that it’s within this callback that you’re usingget_query_var()
.wp_super_cache_query_vars
doesn’t get employed untiltemplate_redirect
, which is long afterplugins_loaded
and it’s at that stage that this error is happening.I’ve applied the change from Github and can confirm that the “Call to a member function get() on null” error is gone now. ??
@paultgoodchild – The output buffer runs at the end of the process, which is (normally) after template_redirect has fired and called wp_super_cache_query_vars(). In that case, everything is fine because wp_super_cache_query_vars() was called and $wp_super_cache_query populated.
In your case, $wp_super_cache_query is empty, and in line 388, in the output buffer, the plugin tries to populate that array by calling wp_super_cache_query_vars(). This caused the error because $wp_query wasn’t set.
So, putting the $wp_query check in wp_super_cache_query_vars() should fix the problem for you because that’s where the query vars are used.
As a side note, this check on $wp_super_cache_query was added in the last release to fix problems with sitemap plugins that generate the sitemap but die() before template_redirect fires, and thus, the array $wp_super_cache_query wasn’t set, but those plugins did set $wp_query because they wanted to identify the request as a sitemap.
Edit: @josklever – excellent news. Looks like we might need a minor point release in the next day or so.
- This reply was modified 7 years, 3 months ago by Donncha O Caoimh (a11n).
Cool, thanks for the explanation – appreciate it!
I tested the change and it works. Thanks!
I’ve noticed same issue after https://github.com/Automattic/wp-super-cache/pull/346. In meantime, I’ve done detail checking. Conflict is with plugin Pretty Link. Creating empty WP Query isn’t perfect solution and it will open new issues.
I created https://github.com/Automattic/wp-super-cache/pull/367. Could you check it?
This PR checks is wp_query object and call wp_super_cache_query_vars only if it’s safe. It works perfectly in my case. As additional improvement, I’ve added checking for PHP errors. If PHP fatal error is occurred, this code will prevent caching.
Regards,
Sasa- This reply was modified 7 years, 3 months ago by Sa?a.
My customer doesn’t have that plugin on the website, so it’s a conflict with another plugin.
This isn’t a plugin conflict and certainly not with Pretty Link. This is using a variable as an object before it’s been instantiated.
If you’re going to use a WordPress variable, at any stage of the WordPress load, ensure it’s ready. Or don’t use it. You can’t assume
$wp_query
has been defined whenever you try to use it if you can’t guarantee when your code will be executed, regardless of the plugin that might lead to your code being called.* I agree, however, that manually creating the WP_Query object instead of WordPress doing it, isn’t ideal and can lead to potential issues bubbling up elsewhere.
I’ve found other plugins with similar behavior. Also, I’ve created my custom code which reproduced this error.
So, this solution seems correct:
if ( wpsc_is_fatal_error() ) { $cache_this_page = false; wp_cache_debug( 'wp_cache_ob_callback: PHP Fatal error occurred. Not caching incomplete page.', 4 ); } elseif ( empty( $wp_super_cache_query ) && is_object( $wp_query ) ) { $wp_super_cache_query = wp_super_cache_query_vars(); }
is_object( $wp_query )
is false in your case and it prevents calling ofwp_super_cache_query_vars()
. It seems as more logical solution. Could you test it?In next condition,
$wp_super_cache_query
is empty and content isn’t cached.Also, I added function
function wpsc_is_fatal_error() { global $wp_super_cache_query; if ( null === ( $error = error_get_last() ) ) { return false; } if ( $error['type'] & ( E_ERROR | E_CORE_ERROR | E_PARSE | E_COMPILE_ERROR | E_USER_ERROR ) ) { $wp_super_cache_query[ 'is_fatal_error' ] = 1; return true; } return false; }
It prevents caching/call of
wp_super_cache_query_vars()
when PHP fatal errors is occurred. Please remember that’s possible case (I’ve tested it):
Fatal error: Allowed memory size of 536870912 bytes exhausted (tried to allocate 20480 bytes) ...
. Then create new object which requires memory is new complication.I think that https://github.com/Automattic/wp-super-cache/pull/367 handles it better than just creating object. So, please test it. I’m open for more testing.
* @paultgoodchild I agree with you. I’m not plugin’s author, but I was trying to improve code in this plugin (because some updates have broken some functionalities on my websites). I’m trying to make good compromise between all changes/proposed solutions. Also, quick pushing important changes without detail testing is making new troubles and it’s magic loop.
- This reply was modified 7 years, 3 months ago by Sa?a.
- The topic ‘Fatal error with latest update’ is closed to new replies.