I'd like to understand what value I should return from a WordPress save_post action function.

This example from the save_post documentation both explicitly and implicitly returns without a value:

function my_project_updated_send_email( $post_id ) {

    // If this is just a revision, don't send the email.
    if ( wp_is_post_revision( $post_id ) )

    $post_title = get_the_title( $post_id );
    $post_url = get_permalink( $post_id );
    $subject = 'A post has been updated';

    $message = "A post has been updated on your website:\n\n";
    $message .= $post_title . ": " . $post_url;

    // Send email to admin.
    wp_mail( '[email protected]', $subject, $message );
add_action( 'save_post', 'my_project_updated_send_email' );

However, this example from the add_meta_box documentation very specifically returns the $post_id that was passed in if it returns early, but returns nothing if the function executes to the end.

 * When the post is saved, saves our custom data.
 * @param int $post_id The ID of the post being saved.
function myplugin_save_postdata( $post_id ) {

   * We need to verify this came from the our screen and with proper authorization,
   * because save_post can be triggered at other times.

  // Check if our nonce is set.
  if ( ! isset( $_POST['myplugin_inner_custom_box_nonce'] ) )
    return $post_id;

  $nonce = $_POST['myplugin_inner_custom_box_nonce'];

  // Verify that the nonce is valid.
  if ( ! wp_verify_nonce( $nonce, 'myplugin_inner_custom_box' ) )
      return $post_id;

  // If this is an autosave, our form has not been submitted, so we don't want to do anything.
  if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) 
      return $post_id;

  // Check the user's permissions.
  if ( 'page' == $_POST['post_type'] ) {

    if ( ! current_user_can( 'edit_page', $post_id ) )
        return $post_id;

  } else {

    if ( ! current_user_can( 'edit_post', $post_id ) )
        return $post_id;

  /* OK, its safe for us to save the data now. */

  // Sanitize user input.
  $mydata = sanitize_text_field( $_POST['myplugin_new_field'] );

  // Update the meta field in the database.
  update_post_meta( $post_id, '_my_meta_value_key', $mydata );
add_action( 'save_post', 'myplugin_save_postdata' );

There's no indication on that page of why it's returning $post_id if it returns early.

There doesn't seem to be any actual documentation on the save_post Codex page one way or the other. I've seen conflicting advice around the web, too.

The example of creating an Action function in the Plugin API documentation looks like it's also a save_post action, and returns the $post_id passed in on success, though it doesn't say why:

function email_friends($post_ID)  {
    $friends = '[email protected],[email protected]';
    mail($friends, "sally's blog updated", 
      'I just put something on my blog: http://blog.example.com');
    return $post_ID;

Can anyone tell me what I, if anything, I should be returning from my save_post actions, and why, preferably with some kind of official reference?

1 Answer 1


Actions should not return anything, and action hooks are not built to do anything with a returned value. (That is what filters are for.)

If you look at the source for that particular hook, you can see that even if you return something nothing happens. Whatever you return isn't captured. It vanishes from the code.

The sample code you found is in my opinion sloppy and confusing. I assume that the point of the return $post_id lines is just to kill the script, which it would do, but all that is really necessary to kill the script is a simple return;. Even a return false; would be less confusing.

  • Thank you! I further allayed my worries by checking the source for do_action(), which clearly discards the result of its call_user_func_array() call... I suppose those examples may have been leftovers from a time when actions and filters were perhaps a bit less distinct... Commented Jan 18, 2014 at 15:19
  • As far as I know actions and filters have always been the way they are-- and they are still not very distinct.
    – s_ha_dum
    Commented Jan 18, 2014 at 15:21

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.