Skip to content

Hooks reference

Culprit Finder offers a small set of actions and filters so add-ons can extend it without touching its code. All hook names start with culprit_finder_.

Every callback runs through a guard, so an add-on can’t break the site:

  • While your callback runs, any attempt to change the list of active plugins (update_option( 'active_plugins', … )) is silently ignored. Culprit Finder never changes your real plugin settings, and neither can a hook.
  • If your callback throws an error, it is skipped. For a filter, the original value is used instead. With WP_DEBUG on, the error is written to the debug log.
  • Session data passed to hooks never contains the secret session token or the emergency exit key.

Several hooks receive $session, an array with these keys:

Key Type Meaning
user_id int The administrator running the session.
created_at int When the session started (Unix time).
expires_at int When it ends if nobody answers (Unix time).
self string Culprit Finder’s own plugin file, always on.
snapshot string[] The active plugins when the session started.
pinned string[] Plugins the user chose to keep on.
deps array Plugin → plugins it requires (within the snapshot).
answers bool[] Answers so far; true means “the problem is still there”.
fixed string[] Plugins on in every step (kept on, their requirements, Culprit Finder).
enabled_now string[] Plugins on in the current step.
problem_url string The broken page’s address, or an empty string.

Plugins are identified by their file path relative to the plugins folder, for example acme-invoices/acme-invoices.php.

$step is an array:

Key Type Meaning
status string asking or done.
phase string baseline, find_first, solo, find_partner, verify or done.
question int The number of the current question (1-based).
estimated_total int About how many answers the search will take.
enabled string[] Plugins on in this step.
disabled string[] Plugins off in this step (for this browser only).
result array|null When done: type, culprits, kept_on.
answers_used int Answers the search has used.

Result types: SINGLE, PAIR, COMPLEX, NOT_PLUGIN, NOTHING_TO_TEST, INCONCLUSIVE.

Fires after a troubleshooting session starts (from the admin page or WP-CLI).

do_action( 'culprit_finder_session_started', array $session, array $step );

$step is the first question.

Fires after an answer or an undo changes the current step.

do_action( 'culprit_finder_step_changed', array $step, array $session, string $cause );

$cause is answer or undo. When an answer finishes the search, culprit_finder_result_found fires first, then this action with a done step.

Fires when a search finishes and its result is saved.

do_action( 'culprit_finder_result_found', array $result, array $session );

$result is the saved result: id, version, result (type, culprits, kept_on), answers, tested, finished_at, plugins (name, version, author, website and requirements of the plugins involved) and env (WordPress and PHP versions, theme, multisite). It contains no user data.

Fires when a session ends.

do_action( 'culprit_finder_session_ended', string $reason, array $session );
$reason When
exit The user pressed Exit or Done, or ran wp culprit-finder exit.
expired Nobody answered for an hour; noticed on the next admin request.
replaced A new session started while one was running.
recovery Someone opened the emergency exit link.
deactivated Culprit Finder was deactivated.

Change the support report. Sections are joined with a blank line, in array order.

apply_filters( 'culprit_finder_report_sections', array $sections, array $result ): array

$sections starts as [ 'result' => …, 'environment' => …, 'footer' => … ], each a block of plain-text lines. Add, change, reorder or remove sections. The report is pasted into public forums, so never add site addresses, user names or email addresses.

add_filter( 'culprit_finder_report_sections', function ( $sections, $result ) {
$sections['acme'] = 'Acme Hosting: PHP workers 4';
return $sections;
}, 10, 2 );

Add a tab to the Culprit Finder page.

apply_filters( 'culprit_finder_admin_tabs', array $tabs ): array

$tabs maps tab ids to labels. The three built-in tabs (troubleshoot, results, help) always come first and can’t be renamed or removed. Ids are passed through sanitize_key().

Render the content of your tab.

do_action( "culprit_finder_render_tab_{$id}", array|null $session );

$session is the running session if this browser owns it, otherwise null. Escape everything you print.

add_filter( 'culprit_finder_admin_tabs', function ( $tabs ) {
$tabs['acme'] = __( 'Acme', 'acme' );
return $tabs;
} );
add_action( 'culprit_finder_render_tab_acme', function ( $session ) {
echo '<p>' . esc_html__( 'Hello from Acme.', 'acme' ) . '</p>';
} );

Answer a step automatically, for example after checking the broken page yourself.

apply_filters( 'culprit_finder_auto_answer', null $answer, array $step, array $session ): null|string

Return 'yes' (the problem is still there), 'no' (it’s gone), or null to let the user answer. Any other value is ignored.

The filter only runs when the administrator who owns the session opens the Troubleshoot tab in that same browser. It never runs for visitors, other users or WP-CLI. Automatic answers count like normal ones, so Undo still works. Culprit Finder asks again after each automatic answer, until you return null or the search finishes.

WordPress is a trademark of the WordPress Foundation. Culprit Finder is not affiliated with or endorsed by the WordPress Foundation.