Tips・Fixing WordPress snags

How to investigate a blank white screen (WP_DEBUG)

How to narrow things down when WordPress goes blank or shows a critical error. Covers the settings that make errors visible with WP_DEBUG, how to read debug.log, and how to recover when you can't even reach the admin screen.

A blank white screen doesn’t mean “there’s no information”—it just means the site is configured not to display errors. The shortest route is to make errors visible first.

define('WP_DEBUG', true);          // turn debug mode on
define('WP_DEBUG_DISPLAY', true);  // show on screen (during development)
define('WP_DEBUG_LOG', true);      // also record to wp-content/debug.log

Now a message like this appears on the page.

Fatal error: Uncaught Error: Call to undefined function my_helper()
in /wp-content/themes/mytheme/functions.php on line 42

It gives you a file name and a line number, and from there all you do is go look.

How to read debug.log

With WP_DEBUG_LOG on, errors are appended to wp-content/debug.log.

  • Look at the bottom (the newest). Each line starts with a timestamp
  • Fatal errorcritical. The page stops here. Fix this first
  • Warning / Notice / Deprecated—it runs, but there’s a problem. Fix these later

You can also write your own messages into it. That’s invaluable where you can’t print var_dump() on screen (Ajax, inside hooks, admin save routines).

error_log('got this far');
error_log(print_r($some_array, true));   // turn arrays into a string first

Narrowing down by symptom

Blank (nothing displayed at all)

  1. Turn WP_DEBUG on and read the error message
  2. If no error appears, suspect the file you just edited (a missing ; in PHP, whitespace after ?>, a stray full-width space)
  3. If you can’t reach the admin screen either, go to “Recovery steps” below

”There has been a critical error on this website.”

That’s a PHP fatal error. If a recovery link (recovery mode) reached the admin email address, you can deactivate the offending plugin or theme from there. Where that email never arrives, use the recovery steps below.

A 500 error (Internal Server Error)

Processing stopped on the server side. Typical causes are a mistake in .htaccess, PHP running out of memory, or a plugin conflict.

define('WP_MEMORY_LIMIT', '256M');

When you suspect .htaccess, rename it to .htaccess-bak and check the page; if that fixes it, rebuild the file by saving “Settings” → “Permalinks” in the admin screen.

Only the admin screen is blank or broken

Look at the Console in your browser’s developer tools. It’s often a JavaScript error, which points to a plugin conflict.

TipsGetting started with developer toolsHow to look at errors in developer tools

Recovery steps when you can’t reach the admin screen

Work over FTP or your host’s file manager. The order matters.

  1. Stop every pluginrename wp-content/plugins to plugins-off. If the site comes back, one of the plugins is the cause
  2. Restore them one at a time—put the name back and activate plugins one by one to identify the culprit
  3. Suspect the theme—rename wp-content/themes/your-active-theme and WordPress automatically falls back to a default theme. If that fixes it, the theme is the cause
  4. Undo your last edit—if you just edited functions.php, revert that change
TipsHow to build a child theme (minimal setup)How to build a child theme

Tools for debugging during development

var_dump($value);                    // shows the type as well
print_r($array);                     // arrays, more readable
wp_die('<pre>' . print_r($v, true) . '</pre>');   // stop here and display
error_log(print_r($v, true));        // send it to the log (doesn't break the page)

When you want to see WordPress-specific values, these two are handy.

global $template;
error_log('template: ' . $template);              // the template in use
error_log(print_r(get_post_meta(get_the_ID()), true));   // every meta value on that post
TipsDon't panic when an error appearsHow to read error messages themselves is covered in this article

When you want to trace SQL and hooks too

WordPress has debugging plugins that show the queries that ran, the template used and a list of hooks right in the admin bar (Query Monitor is the standard). Once you reach the “why is this slow?” or “which hook is taking effect?” stage, it’s worth installing one.

During development these two are useful as well.

define('SCRIPT_DEBUG', true);   // load the uncompressed CSS and JS
define('SAVEQUERIES', true);    // record the SQL that runs (pair it with a debugging plugin)

Turn both off in production.

Summary

  1. Start by turning WP_DEBUG on in wp-config.php—a file name and line number solves most of it
  2. On a live site, display off, log on. Read the newest lines of wp-content/debug.log
  3. When you can’t reach the admin screen, rename the plugins folder to deactivate everything, then restore one at a time
  4. Where you can’t print to the screen, debug with error_log(). Put the settings back when you’re done

With a procedure for narrowing things down, even a blank white screen stops being scary.

FAQ

My WordPress site went blank. What should I do first?
Set WP_DEBUG to true in wp-config.php so the error message is displayed. If the file name and line number in the error point at what you just edited, that's your cause. If you can't reach the admin screen either, rename the plugins folder over FTP or a file manager to deactivate everything and narrow it down.
Can I log errors instead of showing them on screen?
Yes. Set WP_DEBUG to true, WP_DEBUG_LOG to true and WP_DEBUG_DISPLAY to false, and everything is recorded only in wp-content/debug.log. Use that combination when investigating a live site.
I see "There has been a critical error on this website."
That's a PHP fatal error. If a recovery link (recovery mode) reached the admin email address, you can deactivate the offending plugin or theme from there. If no email arrived, check the details with WP_DEBUG.
Is it safe to turn WP_DEBUG on for a live site?
Error messages expose things like file paths, so turn display off (WP_DEBUG_DISPLAY to false) and record to the log instead. Once you're done, set WP_DEBUG itself back to false.