From a2d4316d8e55a1a54c1bb2e844ed2c68042f07ab Mon Sep 17 00:00:00 2001 From: fabiomsnunes Date: Thu, 12 Nov 2026 18:27:52 +0000 Subject: [PATCH 1/4] Posts, Post Types: Bail early in _reset_front_page_settings_for_post() when the post no longer exists. --- src/wp-includes/post.php | 8 ++++++++ tests/phpunit/tests/post/wpDeletePost.php | 25 +++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/wp-includes/post.php b/src/wp-includes/post.php index e0afc05cd1b54..0927380067a9c 100644 --- a/src/wp-includes/post.php +++ b/src/wp-includes/post.php @@ -4226,6 +4226,14 @@ function wp_delete_post( $post_id = 0, $force_delete = false ) { function _reset_front_page_settings_for_post( $post_id ) { $post = get_post( $post_id ); + /* + * The post may already be gone, e.g. when another request deleted it + * while this one was deleting it. + */ + if ( ! $post ) { + return; + } + if ( 'page' === $post->post_type ) { /* * If the page is defined in option page_on_front or post_for_posts, diff --git a/tests/phpunit/tests/post/wpDeletePost.php b/tests/phpunit/tests/post/wpDeletePost.php index 3c2a40fa92bec..66c0290189652 100644 --- a/tests/phpunit/tests/post/wpDeletePost.php +++ b/tests/phpunit/tests/post/wpDeletePost.php @@ -206,4 +206,29 @@ public function test_wp_delete_post_reassigns_attachments_to_parent() { $this->assertSame( $parent_post_id, get_post( $attachment_id )->post_parent ); } + + /** + * Tests that wp_delete_post() does not trigger a warning when the post is deleted + * by another process while it is being deleted. + * + * The concurrent delete is simulated by deleting the post from a `before_delete_post` + * callback that runs before `_reset_front_page_settings_for_post()`. + * + * @ticket NNNNN + * + * @covers ::_reset_front_page_settings_for_post + */ + public function test_wp_delete_post_handles_post_deleted_concurrently() { + $post_id = self::factory()->post->create(); + + $delete_concurrently = static function ( $post_id_being_deleted ) use ( &$delete_concurrently ) { + remove_action( 'before_delete_post', $delete_concurrently, 1 ); + wp_delete_post( $post_id_being_deleted, true ); + }; + add_action( 'before_delete_post', $delete_concurrently, 1 ); + + wp_delete_post( $post_id, true ); + + $this->assertNull( get_post( $post_id ) ); + } } From 848ce69b8f6204803676bbe41c9c3f2fd44b3c61 Mon Sep 17 00:00:00 2001 From: fabiomsnunes Date: Thu, 12 Nov 2026 19:15:30 +0000 Subject: [PATCH 2/4] Tests: Reference the Trac ticket in the concurrent delete test. --- tests/phpunit/tests/post/wpDeletePost.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/post/wpDeletePost.php b/tests/phpunit/tests/post/wpDeletePost.php index 66c0290189652..77d2299dd8981 100644 --- a/tests/phpunit/tests/post/wpDeletePost.php +++ b/tests/phpunit/tests/post/wpDeletePost.php @@ -214,7 +214,7 @@ public function test_wp_delete_post_reassigns_attachments_to_parent() { * The concurrent delete is simulated by deleting the post from a `before_delete_post` * callback that runs before `_reset_front_page_settings_for_post()`. * - * @ticket NNNNN + * @ticket 66684 * * @covers ::_reset_front_page_settings_for_post */ From cc44c5841eee880a0c4bdb5dfa5c19918fd8049f Mon Sep 17 00:00:00 2001 From: fabiomsnunes Date: Thu, 12 Nov 2026 19:39:31 +0000 Subject: [PATCH 3/4] Posts, Post Types: Remove the comment on the early return in _reset_front_page_settings_for_post(). --- src/wp-includes/post.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/wp-includes/post.php b/src/wp-includes/post.php index 0927380067a9c..f4907e1e9085e 100644 --- a/src/wp-includes/post.php +++ b/src/wp-includes/post.php @@ -4226,10 +4226,6 @@ function wp_delete_post( $post_id = 0, $force_delete = false ) { function _reset_front_page_settings_for_post( $post_id ) { $post = get_post( $post_id ); - /* - * The post may already be gone, e.g. when another request deleted it - * while this one was deleting it. - */ if ( ! $post ) { return; } From b43c08fe409af46ef967c94d0325259e4e8e6722 Mon Sep 17 00:00:00 2001 From: fabiomsnunes Date: Thu, 12 Nov 2026 20:13:56 +0000 Subject: [PATCH 4/4] Multisite: Bail early in _update_blog_date_on_post_delete() when the post no longer exists. --- src/wp-includes/ms-blogs.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/wp-includes/ms-blogs.php b/src/wp-includes/ms-blogs.php index d791dd2f4526d..c963161bc9c18 100644 --- a/src/wp-includes/ms-blogs.php +++ b/src/wp-includes/ms-blogs.php @@ -872,6 +872,10 @@ function _update_blog_date_on_post_publish( $new_status, $old_status, $post ) { function _update_blog_date_on_post_delete( $post_id ) { $post = get_post( $post_id ); + if ( ! $post ) { + return; + } + $post_type_obj = get_post_type_object( $post->post_type ); if ( ! $post_type_obj || ! $post_type_obj->public ) { return;