Basically it goes like this (relevant steps only):
plugins.php
page callsactivate_plugin()
function.- Function starts output buffering.
- Includes plugin file.
- Fires
activate_plugin
action. - Fires
'activate_' . trim( $plugin )
action. - Fires
activated_plugin
action. - If buffer is not empty it creates
WP_Error
object and returns it. plugins.php
page checks for error and displays error message.
So output happens somewhere between steps 2 and 7. If it comes up for multiple plugins then steps 3 and 5 are safe to exclude, they are plugin-specific.
So it is likely something in either activate_plugin
or activated_plugin
. Also actual unwanted output is passed in WP_Error
object but not used (only its length).
I’d try to dump hooks first, will take bit of extra code in core a bit to get to that output in WP_Error
object.