I'm working on a plugin and having some difficulties getting a new table created. I get the "The plugin generated x characters of unexpected output during activation" error. Is there a way of viewing the actual error? I believe that a redirect is involved in this process, hence the reason I don't see the actual error output. I have all error reporting and logging on, but still I get nothing.

  • 2
    I figured out a way to see the error--I executed exit() on line 1569 of wp-admin/includes/upgrade.php. It is called at the end of the dbDelta function, which allowed me to see the output that was generated and quickly fix the problem. I'm still interested in learning other methods for this that would not require a core hack.
    – tollmanz
    Jul 28, 2011 at 1:17

3 Answers 3


Interestingly the ability to display errors and output from a plugin on activation seems to be build in to WordPress. If you take a look at wp-admin/plugins.php there's a case in the $action switch statement that says error_scrape -- hinted at in Lars' answer.

Looks like this:

// wp-admin/plugins.php
case 'error_scrape':
    if ( ! current_user_can('activate_plugins') )
        wp_die(__('You do not have sufficient permissions to activate plugins for this site.'));

    check_admin_referer('plugin-activation-error_' . $plugin);

    $valid = validate_plugin($plugin);
    if ( is_wp_error($valid) )

    if ( ! WP_DEBUG ) {

    @ini_set('display_errors', true); //Ensure that Fatal errors are displayed.
    // Go back to "sandbox" scope so we get the same errors as before
    function plugin_sandbox_scrape( $plugin ) {
        include( WP_PLUGIN_DIR . '/' . $plugin );
    plugin_sandbox_scrape( $plugin );
    do_action('activate_' . $plugin);

As you can see, it mimics the plugin activation senario, but it doesn't actually activate the plugin. It includes the plugin file, calls the activate hook, then exits. It does all this without output buffering so you can see what's happening.

SO, if that's already there, we just need to expose it. A bit of digging in wp-admin/plugins.php shows we need a nonce to verify. So we can copy that and study how the plugins list table builds its activation links. Then simply add an error scrape link on the inactive plugins. Click it, and see your errors.

Just hook into plugin_action_links and add the link:

add_filter('plugin_action_links', 'wpse24278_add_scrape', 10, 2);
 * Add an "Error Scrape" action to inactive plugins.
 * @uses    is_plugin_active
 * @return  array
function wpse24278_add_scrape($actions, $plugin)
    global $status, $page, $s;

    // leave active plugins alone
    if (is_plugin_active($plugin)) {
        return $actions;

    // build the url, identical to the activate URL, see the
    // plugings list table for more information.
    $url = add_query_arg(array(
        'action'            => 'error_scrape',
        'plugin'            => $plugin,
        'plugin_status'     => $status,
        'paged'             => $page,
        's'                 => $s,
    ), admin_url('plugins.php'));

    // add our action.
    $actions['error_scrape'] = sprintf(
        '<a href="%s" title="%s" class="edit">%s</a>',
        wp_nonce_url($url, 'plugin-activation-error_' . $plugin), // see `wp-admin/plugins.php` for the nonce name
        esc_attr__('Check for Errors', 'wpse'),
        esc_html__('Error Scrape', 'wpse')

    return $actions;

Here is the above wrapped up in a plugin.

  • I wish there was a way to +1 this a hundred times. You just made my day. Mar 28, 2014 at 15:53

Interesting question, so I had a look on Google and some guy named Jason had a solution:

br_trigger_error('Some error message', E_USER_ERROR);

function br_trigger_error($message, $errno) {
      &amp;&amp; $_GET['action'] == 'error_scrape') {
    echo '<strong>' . $message . '</strong>';
} else {
    trigger_error($message, $errno);

From http://www.squarepenguin.com/wordpress/?p=6 that has more details as well.


I just found a way, all props to itzco and hungrycoder. I've added the hook parameters.

add_action( 'activated_plugin', 'save_error_wpse_24278', 10, 2 );

function save_error_wpse_24278( $plugin, $network_wide )
        WP_CONTENT_DIR. '/error_activation.html', 
        $plugin . ob_get_contents() 
    //update_option( 'plugin_error',  ob_get_contents() );
  • 1
    Would be better with wp_upload_dir instead of a hardcoded path to wp-content. Feb 3, 2013 at 4:51
  • @chrisguitarguy, I guess WP_CONTENT_DIR does the same job, and I think it makes more sense in there than inside /uploads/...
    – brasofilo
    Feb 6, 2013 at 0:59
  • My WP_CONTENT_DIR is not writable, just my uploads folder. If that's anything. Feb 6, 2013 at 2:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.