I've read dozens and dozens of posts on this error and I'm still not getting it. So, I'd like to add to the plethora of ajax 400 discussions. This is a plugin that displays/validates/records a simple form called with a shortcode.

Root plugin file looks like this:

        'Able Signup',                //  page title
        'Able Signup',                //  menu title
        'manage_options',             //  capability (role of who can use)
        'able_signup',                //  menu slug
        'able_signups',               //  function in .php app that gets called when clicking
        'dashicons-clipboard',        //  icon
        4                             //  position in menu
    require_once ( "apps/view_signups.php");  //for later dump of DB
    require_once ( 'apps/save_signups.php' ); //process submitted form <== ??? 
add_action( 'admin_menu', 'wpdocs_register_able_signup_menu_page' );

// starting of a shortcode
function able_show_form_template( $atts ) {
    require_once ( 'apps/form_signups.php' );

    able_display_form_template( $atts ); //name of function called 
    return ob_get_clean();
add_shortcode( 'add_signup_form', 'able_show_form_template' ); // [add_signup_form id='01']

The ajax on the form page looks like this:

$j('#signup').on('submit', function(){
    //console.log("submit fired"); //works
    //console.log("ajax_url"); //set in functions.php and works
        type: 'POST',
        url: ajax_url,
        data: {
            action:     'save-form',
            full_name:  $j('#full_name').val(),
            //more data
        success: function (response) {
    return false;

And finally, the called PHP file for processing:

// in apps/save_signups.php
function save_form() {
    if ( wp_verify_nonce( $_POST['signup_nonce'], '' ) ) {
       //process form
        wp_send_json( $messages );
    } else {
        wp_send_json( "Bad form" );
add_action( 'wp_ajax_save_form', 'save_form' );
add_action( 'wp_ajax_nopriv_save_form', 'save_form' );

Apache error.log shows this, but didn't make much sense:

ndefined offset: 0 in /var/www/susites/abledesignbuild/htdocs/wp-includes/class-wp-query.php on line 3284'

What am I missing? The only thing I can think of is that my save_signups.php is not "seen" but not sure how to tell.

Thanks! Brad


Your hook name uses an underscore:

add_action( 'wp_ajax_save_form', 'save_form' );
add_action( 'wp_ajax_nopriv_save_form', 'save_form' );

But your action uses a hyphen.

action:     'save-form'

These need to match:

action:     'save_form'

Also, your AJAX callback appears to be in apps/save_signups.php, but you are only requiring that file inside the admin_menu hook:

     require_once ( 'apps/save_signups.php' ); //process submitted form <== ??? 
add_action( 'admin_menu', 'wpdocs_register_able_signup_menu_page' );

But seeing as there's no admin menu needed for AJAX requests, that hook doesn’t run on requests to admin-ajax.php, so the callback is never registered.

I don't know what other code is in apps/save_signups.php, so I can't say whether that entire file should be required anywhere else, but your add_action() calls that hook save_form() should be hooked outside of any other hooks.

| improve this answer | |
  • Thanks. I have read in lots of places that match is usually the culprit (also, I was told that wp-ajax converts hyphens to underscores in the process). Anyway, I changed it per your suggestion and still getting the error. Wondering if the function save_form is loaded/available. Any debugging suggestions. – breadwild Sep 8 at 12:34
  • Your AJAX callback appears to be in apps/save_signups.php, but you are only requiring that file inside the admin_menu hook, but that hook doesn’t run on AJAX requests. – Jacob Peattie Sep 8 at 12:48
  • Thanks Jacob, where would I place that require_once statement? in that plugin root file? where in the file? Or somewhere else? If you have any resources I could check out, that would be fine. – breadwild Sep 8 at 14:31
  • I don't know. I don't know what else in it. Just make sure that your code that hooks save_form into the wp_ajax_ hooks runs outside of another hook. – Jacob Peattie Sep 8 at 14:37
  • Solved it with a `require_once('save_form.php') in the root file of my plugin. – breadwild Sep 8 at 20:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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