wppaste
WordPress

wp_trigger_error( string $function_name, string $message, int $error_level = E_USER_NOTICE )

Since
6.4.0
Source
wp-includes/functions.php:6091

Emits a PHP-level error, warning, notice, or deprecation message through trigger_error(), but only runs the check and message at all when WP_DEBUG is true. It runs the message through wp_kses() first, so only 'a' (with href), 'code', 'br', 'em', and 'strong' tags and http/https links survive, everything else is escaped or stripped. Passing E_USER_ERROR as the error level throws a catchable WP_Exception instead of calling trigger_error(), which will be fatal if nothing catches it. A companion action, wp_trigger_error_run, fires before the message is sanitized, letting you log or backtrace every call site.

Generates a user-level error/warning/notice/deprecation message.

Description

Generates the message when WP_DEBUG is true.

Compatibility

WordPress
since 6.4.0
PHP
7.4–8.6-dev
  • 6.7.10
  • 6.8.11
  • 6.9.10
  • 7.0.7
  • 7.1.3

Present in every tracked release (6.7.10 to 7.1.3), and compiles on PHP 7.4 through 8.6-dev.

Parameters

$function_namestring
The function that triggered the error.
$messagestring
The message explaining the error.
The message can contain allowed HTML 'a' (with href), 'code', 'br', 'em', and 'strong' tags and http or https protocols.
If it contains other HTML tags or protocols, the message should be escaped before passing to this function to avoid being stripped wp_kses().
$error_levelintoptional
The designated error type for this error.
Only works with E_USER family of constants. Default E_USER_NOTICE.Default: E_USER_NOTICE

Code examples

Every example is editable and runs in a real WordPress booted in your browser by WordPress Playground. Press Run, then edit the code: clicking away re-runs it. Nothing is sent anywhere until you do.

Warn plugin or theme code when expected post meta is missing

A helper that formats a price from post meta calls wp_trigger_error() when the meta key is empty, and a temporary error handler prints the resulting notice so the sandbox has visible output.

function wpdocs_get_price_html( $post_id ) {
	$price = get_post_meta( $post_id, 'price', true );

	if ( '' === $price ) {
		wp_trigger_error(
			__FUNCTION__,
			'No <code>price</code> meta was found for post ID ' . absint( $post_id ) . ', returning an empty string.'
		);
		return '';
	}

	return '$' . esc_html( $price );
}

if ( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG ) {
	echo esc_html( 'WP_DEBUG is off in this sandbox, so wp_trigger_error() returns immediately and never reaches trigger_error().' );
} else {
	set_error_handler(
		function ( $errno, $errstr ) {
			echo esc_html( 'PHP notice raised: ' . $errstr );
			return true;
		}
	);

	// Post 2 already has `price` meta, post 3 does not, so only post 3 triggers the notice.
	echo esc_html( 'Post 2: ' . wpdocs_get_price_html( 2 ) . ' | ' );
	echo wpdocs_get_price_html( 3 );

	restore_error_handler();
}

The output depends on WP_DEBUG being enabled in the sandbox's wp-config.php, since the function bails out silently otherwise.

Stop execution with a catchable exception instead of a silent PHP warning

Passing E_USER_ERROR makes wp_trigger_error() throw a WP_Exception rather than call trigger_error(), which lets the caller decide what happens next.

if ( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG ) {
	echo esc_html( 'WP_DEBUG is off in this sandbox, so wp_trigger_error() returns immediately and no exception is thrown.' );
} else {
	try {
		wp_trigger_error(
			'wpdocs_require_admin_context',
			'This routine must only run for an <strong>administrator</strong> account.',
			E_USER_ERROR
		);
		echo esc_html( 'This line never runs because the exception above stops execution.' );
	} catch ( WP_Exception $e ) {
		echo esc_html( 'Caught WP_Exception: ' . $e->getMessage() );
	}
}

Common problems and fixes · 4

Why doesn't wp_trigger_error() do anything on my site?

The function's first line checks WP_DEBUG and returns immediately if it is not true, before the wp_trigger_error_run action even fires and before trigger_error() is ever called.

Why did my HTML get stripped out of the error message?

The message is passed through wp_kses() with a fixed allowlist of 'a' (href only), 'code', 'br', 'em', 'strong', and only http/https protocols, so anything else is escaped away.

Why did my site die instead of showing a warning in the log?

Passing E_USER_ERROR as $error_level makes the function throw a new WP_Exception instead of calling trigger_error(). If nothing in the call stack catches that exception, PHP treats it as an uncaught exception and the request fatals.

Can I intercept every wp_trigger_error() call for logging?

Hook the wp_trigger_error_run action, which receives $function_name, $message, and $error_level before the message is run through wp_kses(). It only fires when WP_DEBUG is enabled, the same gate the rest of the function uses.

Alternatives and related functions

_doing_it_wrong
When you want WordPress's standard 'function called incorrectly' notice format instead of composing your own message.
_deprecated_function
When you are marking an entire function as deprecated rather than raising a general warning inside it.
_deprecated_argument
When a specific parameter is deprecated but the function itself still works.
trigger_error
When you need a plain PHP notice or warning without WordPress's WP_DEBUG gate or wp_kses() message filtering.

Performance profile

How much work a call to wp_trigger_error() does, and what it touches: the algorithmic scaling, the Zend instruction count per call across PHP versions, the hooks it hands control to, and the core code that calls it. Measured from the compiled opcodes, not a stopwatch, so every number is identical on any machine running the same PHP version, and every function in core is ranked by cost.

Cost class
Trivial

Touches nothing outside its own arguments.

Scaling
Constant

No loop in the body: the same number of instructions runs whatever you pass in.

Instructions
6–30

Executed per call on PHP 8.5, depending on the branch taken. The body compiles to 35.

Plugin surface
1 hook

Third-party callbacks on 'wp_trigger_error_run' run inside this call, and their cost is not bounded by anything here.

Called by
44

44 places in core call this, so the cost is paid more often than your own code shows.

What it touches

  • hookthird-party callbacksdo_action()called directly

What one call costs · 3 distinct outcomes

One number would be a lie: the work depends on which branch runs. These are every distinct cost wp_trigger_error() can have, taken from its control-flow graph on PHP 8.5.

WhenInstructionsCalls it makes
always6none
$error_level === 25625–29do_action(), wp_kses()
$error_level !== 25626–30do_action(), wp_kses(), trigger_error()

Across PHP versions

PHPCompiledExecutedBranchesNotes
8.6-dev356–303
8.5356–303
8.4356–3032 fewer instructions than PHP 8.3
8.3376–323
8.2376–323
8.1376–323
7.4376–323

An instruction is not a fixed amount of time, so a matching count is not necessarily the same speed; what it rules out is a difference in the work itself.

Hooks and filters fired · 1

One hook fires while wp_trigger_error() runs, in this order:

  1. do_action( wp_trigger_error_run )actionline 6109 (+18 into the body)

    Fires when the given function triggers a user-level error/warning/notice/deprecation message.

Uses · 3

  • do_action()Calls the callback functions that have been added to an action hook.
  • wp_kses()Filters text content and strips out disallowed HTML.
  • WP_Exception::__construct()

Used by · 44

Show all 44

Source code

function wp_trigger_error( $function_name, $message, $error_level = E_USER_NOTICE ) { 	// Bail out if WP_DEBUG is not turned on.	if ( ! WP_DEBUG ) {		return;	} 	/**	 * Fires when the given function triggers a user-level error/warning/notice/deprecation message.	 *	 * Can be used for debug backtracking.	 *	 * @since 6.4.0	 *	 * @param string $function_name The function that was called.	 * @param string $message       A message explaining what has been done incorrectly.	 * @param int    $error_level   The designated error type for this error.	 */	do_action( 'wp_trigger_error_run', $function_name, $message, $error_level ); 	if ( ! empty( $function_name ) ) {		$message = sprintf( '%s(): %s', $function_name, $message );	} 	$message = wp_kses(		$message,		array(			'a'      => array( 'href' => true ),			'br'     => array(),			'code'   => array(),			'em'     => array(),			'strong' => array(),		),		array( 'http', 'https' )	); 	if ( E_USER_ERROR === $error_level ) {		throw new WP_Exception( $message );	} 	trigger_error( $message, $error_level );}

Changelog

Introduced in 6.4.0. Unchanged from 6.7.10 through 7.1.3.

  1. 6.7.10
  2. 6.8.11
  3. 6.9.10
  4. 7.0.7
  5. 7.1.3

Signature, return type and hooks compared across 5 parsed releases.

About this page

Parsed data
Generated from the wordpress-develop 6.9.10 tag, from src/wp-includes/functions.php, and regenerated for each WordPress release so it tracks the code rather than a snapshot of it.
Corrections
Something wrong on this page? Report it and it gets fixed in the next regeneration.