Obscure WordPress Errors – Why? Where? and How?

WordPress Error 1

‘You do not have sufficient permissions to access this page.’

This error is activated within the file wp-admin/menu.php which in turn gets included by wp-admin/admin.php which gets called by almost every WordPress administration page.

Here is a code snippet from wp-admin/menu.php where the error message is reported –

<?php
if (! user_can_access_admin_page()) {
      do_action('admin_page_access_denied');
      wp_die( __('You do not have sufficient permissions to access this page.') );
 }
?>

As you can see from the code snippet above, a good way to debug this error is by hooking into the admin_page_access_denied action in your plugin or your theme functions.php file.

<?php
add_action('admin_page_access_denied', 'debug_page_access');

function debug_page_access() {
	global $pagenow;
	global $menu;
	global $submenu;
	global $_wp_menu_nopriv;
	global $_wp_submenu_nopriv;
	global $plugin_page;
	global $_registered_pages;

	$parent = get_admin_page_parent();
	$hookname = get_plugin_page_hookname($plugin_page, $parent);

	echo "Pagenow = " . $pagenow . "<br/>";
	echo "Parent = " . $parent . "<br/>";
	echo "Hookname = " . $hookname . "<br/>";
	
	echo "Menu = " . $menu . "<br/>";
	echo "Submenu = " . $submenu[$parent] . "<br/>";
	echo "Menu nopriv = " . $_wp_menu_nopriv . "<br/>";
	echo "Submenu nopriv = " . $_wp_submenu_nopriv[$parent][$plugin_page] . "<br/>";
	echo "Plugin page = " . $plugin_page . "<br/>";
	echo "Registered pages = " . $_registered_pages[$hookname] . "<br/>";
	
}
?>

In the debug_page_access function we print out a series of global variables used in the user_can_access_admin_page check. By doing this, we can determine where the admin page failure is coming from.

The user_can_access_admin_page function is defined in wp-admin/includes/plugin.php.

WordPress Error 2

Are you sure you want to do this?

This error is the result of a WordPress nonce check failure.

In particular, this error is reported by the function wp_nonce_ays which is defined in wp-includes/functions.php.

The wp_nonce_ays function is called by the check_admin_referer function which appears everywhere within the WordPress administration areas (i.e. WordPress dashboard).

Below is the check_admin_referer source from the wp-includes/pluggable.php file.

<?php
function check_admin_referer($action = -1, $query_arg = '_wpnonce') {
	$adminurl = strtolower(admin_url());
	$referer = strtolower(wp_get_referer());
	$result = isset($_REQUEST[$query_arg]) ? wp_verify_nonce($_REQUEST[$query_arg], $action) : false;
	if ( !$result && !(-1 == $action && strpos($referer, $adminurl) !== false) ) {
		wp_nonce_ays($action);
		die();
	}
	do_action('check_admin_referer', $action, $result);
	return $result;
}endif;
?>

The function has three required conditions –

  1. Line 5 – You must pass a nonce check.
  2. Line 6 – You must pass the function an action.
  3. Line 6 – The page (php file) calling the function (i.e., wp_get_referer) must be an administration url (as defined by the admin_url function). admin_url simply gets the administration path of the current blog – which can be the WordPress default (wp-admin) or which can be overridden by the admin_url filter.

The ‘Are you sure you want to do this?’ error comes from a failure in one of these areas.

WordPress Errors

These are the two most common errors I came across while writing plugins and themes in WordPress.

If you come across other obscure WordPress errors, please let me know and I will add it to the post.

Related Articles

Comments

  1. says

    Hello again,

    I am using the admin_page_access_denied hook in Multisite, where users can very often come across it. Is there a way to not only add your own (debug) information to the admin_page_access_denied hook, but get rid of wordpress’ really unfriendly message?

    Would it cause problems if my function (debug_page_access, in this example) just displayed a user friendly message and exited (exit()) so that WP message doesn’t get executed?

    Thanks!

    Thanks!

    • says

      ok, so I went ahead and tried it; if you place your desired message into a variable, instead of echoing it, and then call wp_die($your_message_variable), it works the same but with your message instead of WP’s. I hope anyway! If you see any pitfalls or drawbacks, please let me know. I’m assuming since the original WP function just builds its own message and calls wp_die anyway, I can do the same and beat it to the punch. But, I’ve been wrong before. thanks!

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>