Callback hooked to post_updated firing on new posts as well

also firing when I create and publish a new post

If you mean something like, you clicked the “Add New” button (which brings you to the post add new page at /wp-admin/post.php), and then you composed your post and finally hit the “Publish” button, then it’s actually normal for the post_updated hook to get fired twice or more.

Why so or what happens is:

  • After you clicked the “Add New” button, WordPress will automagically create a post with the auto-draft status (post_status = auto-draft).

  • While composing your post, WordPress will auto-save the post so that you don’t lose what you’ve composed thus far, and for each auto-save, the post_updated hook will be fired. And note that, during an auto-save, the post status is set to draft.

  • And after you hit the “Publish” button, WordPress updates the post (with the status changed from auto-draft or draft to publish), and then the post_updated hook will be fired once more.

So as you could see, the hook could get fired at least twice when you manually create and publish a post.

But if you do that programmatically, e.g. using wp_insert_post(), then the hook will not be fired. Note though, if you have plugins or custom code in your theme, the hook might be fired, e.g. a code that runs via save_post and modifies the post slug then call wp_update_post():

// In a default WordPress setup/installation:

// This will not fire the post_updated hook.
$id = wp_insert_post( array(
    'post_title'  => 'Just testing',
    'post_status' => 'publish',
) );

// And this will fire it, but just once.
wp_update_post( array(
    'ID'           => $id,
    'post_content' => 'Sample content',
) );

And I think you might want to execute your code only if the post is not being auto-saved, either as an auto-draft or revision.

So for that purpose, you can check if the constant DOING_AUTOSAVE is defined and that it’s true-ish:

// In your function (maybe_update_author_archive_status_on_post_update()), at the top:
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
    return;
}