I use add_theme_page() within my child theme's functions.php implemented something like this...

// other functions located here that create a custom options page in the Dashboard.

function my_menu() {
    if ( 'save' == $_REQUEST['action'] ) {
        echo '<meta http-equiv="refresh" content="0;url=themes.php?page=functions.php&saved=true">';

add_action('admin_menu', 'my_menu');

As per the WordPress docs:

NOTE: If you're running into the »You do not have sufficient permissions to access this page.« message in a wp_die() screen, then you've hooked too early. The hook you should use is admin_menu.

This is exactly the error I'm getting right after saving my options. However, I've used the correct hook as recommended.

This error only occurs if I move my function into a new file and do use a require_once within funtions.php. I was organizing my code as per this answer.


Why does this break simply by moving the function into an external file? I thought maybe it had to do with placement, but the require_once() is in the exact position where the original code was placed.

  • When the code is inside of functions.php, it works fine.

  • When the code is moved to an external file and reference with require_once(), it breaks (error messages upon save as per the referenced docs above).

Obviously, for now, I'm keeping it within function.php, but maybe somebody can explain why it's breaking when I move it.


This is not a file path issue. Every file referenced by require_once() is being found and included. The problem seems to be how it's being executed.

Please read this answer: https://wordpress.stackexchange.com/a/1406/11092

EDIT 2 - revised 1/16/13

This is a stripped down version that was verified to fully demonstrate the issue. This code constructs a submenu page under "Appearance" called "Theme Options". When you click the "Save Options" button, the page is supposed to reload and show a "your-theme settings saved" message. However, instead it shows the WordPress error page, "You do not have sufficient permissions to access this page." Simply moving the last function into functions.php clears up this permissions issue. I would like to know why and how I can fix it.

in functions.php file:



in my child-theme-directory, includes/functions-test.php file:


$themename = wp_get_theme();

function mytheme_admin() {

    global $themename;

    if ( $_REQUEST['saved'] ) echo '<div id="message" class="updated fade"><p><strong>'.$themename.' settings saved.</strong></p></div>';


    <div class="wrap">
        <h2><?php echo $themename; ?> Options</h2>
        <div style="border-bottom: 1px dotted #000; padding-bottom: 10px; margin: 10px;">Options specfic to this theme.</div>
        <form method="post">
            <p class="submit">
                <input name="save" type="submit" class="button button-primary" value="Save Options" />    
                <input type="hidden" name="action" value="save" />


function wp_initialize_the_theme_load() {
    if (!function_exists("wp_initialize_the_theme")) { 

add_action('admin_menu', 'mytheme_add_admin');

/*  move only the following function to 'functions.php' and the problem is gone

function mytheme_add_admin() {
    global $themename, $shortname;  
    if ( $_GET['page'] == basename(__FILE__) ) {    
        if ( 'save' == $_REQUEST['action'] ) {
            echo '<meta http-equiv="refresh" content="0;url=themes.php?page=functions.php&saved=true">';
    add_theme_page($themename." Options", "Theme Options", 'edit_theme_options', basename(__FILE__), 'mytheme_admin');

1 Answer 1


I noticed the URL of the custom Dashboard page is this...


Notice how the page is the name of my external functions in includes/functions-test.php.

The problem is in this line, the one that refreshes the page just before the permission error...

echo '<meta http-equiv="refresh" content="0;url=themes.php?page=functions.php&saved=true">';

Now it seems so obvious. Look at the page parameter in the URL... it's functions.php where it should be the name of my includes file, functions-test.php.

This is the fix...

echo '<meta http-equiv="refresh" content="0;url=themes.php?page=functions-test.php&saved=true">';

Now I wonder if there's a more robust solution than having a hard coded file name.


And without a hard coded filename... in other words, using basename(__FILE__) instead and I could have moved this code anywhere without the headache.

echo '<meta http-equiv="refresh" content="0;url=themes.php?page=' . basename(__FILE__) . '&saved=true">';

Thank-you to troubleshooting suggestions by @ChipBennett.


Taking it one step further, I was able to completely remove the meta refresh; and die;, where instead I use the action of the form element as it was intended. This is the same form action as used in the default WordPress Appearance pages.

<form action="<?php echo esc_url( add_query_arg( 'saved', true ) ) ?>" method="post">

add_query_arg( 'saved', true ) means that when the page redirects back to itself, on form submission, it will have &saved=1 appended into its query string. This is the only part this code needs in order to display the "options saved" message. The very sloppy meta refresh; die with its hard coded URL, the root of the original problem, has been fully eradicated.

FYI: This is a project where I must extract the client's original options and functionality from their "custom" theme and move them into a child theme of Twenty Thirteen. The original broken theme that uses these sloppy coding practices is called Delicate.

  • @Sparky Most of your questions and answers suffer from comment explosion. Please keep it under control and work more with edits to your question/answer than with comments. Thanks.
    – kaiser
    Feb 9, 2014 at 12:01
  • 1
    @kaiser, hyperbole... in fact, "most" of my eight questions/answers have very few to no comments at all. I strive to conduct myself here as well as I do on StackOverflow where I've built up a respectable 28K rep. Admittedly, this particular question contained many comments because a "more experienced" user, who couldn't see the real problem, insisted on arguing something that was clearly excluded by my OP. It takes more than one user to make a "comment explosion" but the one with the low rep will take the blame... I'll keep that in mind moving forward. Thank-you.
    – Sparky
    Feb 9, 2014 at 16:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.