wp-activate.php causing white screen of death

[note: I solved the problem before asking this question and thought others would find my research/solution helpful, see Can I answer my own question?]

The site in question uses a custom theme and site-specific plugin (that registers custom post types, custom taxonomies, etc), both of which I’ve written.

It turns out that the wp-activate.php bootstrap results in plugins not being loaded…which came as quite a shock to me (and is not documented anywhere that I can find).

My theme’s header.php calls one of the methods defined in the site-specific plugin. Since plugins aren’t loaded when wp-activate.php runs, that method isn’t defined and PHP dies. To make matters worse, the wp-activate.php bootstrap also disables PHP error messages (even when WP_DEBUG is set to true), hence, the white screen of death 🙁

Solution

To solve the problem, I hooked into activate_header (the first hook fired after the wp-active.php bootstrap) and loaded the site-specific plugin myself, as follows:

add_action ('activate_header', 'load_site_specific_plugin') ;

function
load_site_specific_plugin ()
{
    if (wp_installing ()) {
        require_once (WP_PLUGIN_DIR . 'path to site-specific plugin') ;
        }

    return ;
}

See the Gory Deatils section below for why I tested wp_installing() before calling require_once().

Alternate Solution

Another solution would be to add a header-wp-activate.php (that doesn’t rely on any methods defined in the site-specific plugin) to my theme. For my purposes, that didn’t seem to be the right choice, but might be for others.

Gory Details

I have no idea why it was decided that wp-activate.php should not load plugins. But here’s a description of the relevant parts of the wp-activate.php bootstrap, and why it results in plugins not being loaded and PHP error messages to not be displayed.

First, wp-activate.php begins with:

define( 'WP_INSTALLING', true );

Defining WP_INSTALLING as true has cascading effects throughout the wp-activate.php bootstrap. Most importantly for the problem I was experiencing, is that wp_get_active_and_valid_plugins() (which is called in wp-settings.php as part of the bootstrap) contains the following:

if ( empty( $active_plugins ) || wp_installing() )
    return array();

Hence, the bootstrap thinks the site doesn’t use any plugins even tho get_option('active_plugins') returns a non-empty array.

To understand why no PHP errors were output when WP died while trying to load my theme’s header.php (again, even tho I have define ('WP_DEBUG', true) ;), we have to look at the way wp_debug_mode() is written. wp_debug_mode() is called before the call to wp_get_active_and_valid_plugins() during the wp-activate.php bootstrap and contains the following:

if ( defined( 'XMLRPC_REQUEST' ) || defined( 'REST_REQUEST' ) || ( defined( 'WP_INSTALLING' ) && WP_INSTALLING ) || wp_doing_ajax() ) {
    @ini_set( 'display_errors', 0 );
}

So, not only does the wp-activate.php bootstrap not load any plugins, it also causes PHP errors that result from that fact to not be displayed; hence, the white screen of death! Argh!!!

Can anyone explain to my why it was decided that the wp-activate.php bootstrap should act this way?

TL;DR: see the comment I left on a thread about the Nextgen Bootstrap/Load Feature Project on Make WordPress Core.

Leave a Comment