WordPress plugin – Error “Plugin generate 2890 characters of unexpected output when activated”

It is unfortunate core only gives you the string length when it has the entire output available to display. However you can find what those unexpected characters are by dumping them (from the output buffer) to a file on activation. Try adding this (outside the plugin you are activating of course, eg. in a PHP file in /wp-content/mu-plugins/)

<?php 
add_action( 'activated_plugin', 'debug_plugin_output', 10, 2 );
function debug_plugin_output( $plugin, $network_wide ) {
    $output = ob_get_contents();
    $file = WP_CONTENT_DIR . '/plugin-output.txt';
    if ( file_exists( $file ) ) {unlink( $file );}
    error_log( $output, 3,  $file);
}

And then after activation you can check the contents of /wp-content/plugin-output.txt… 🙂

Alternatively, you could dump the output buffer directly and force exit (this will short-circuit multiple activations and prevent WordPress redirecting back to the plugin screen however):

<?php 
add_action( 'activated_plugin', 'debug_plugin_output', 10, 2 );
function debug_plugin_output( $plugin, $network_wide ) {
    $output = ob_get_contents();
    if ( !empty($output) ) {
        echo "Activation of plugin '" . $plugin . "'";
        echo " generated " . strlen( $output ) . " characters of unexpected output:<br><br>";
        echo "<textarea rows="100" cols="40">" . $output . "</textarea>";
        exit;
    }        
}