Make WordPress Core

Opened 4 years ago

Last modified 3 years ago

#48903 new defect (bug)

Drafts or pending posts overwrites existing published post with same url

Reported by: uatania's profile uatania Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 5.3
Component: Permalinks Keywords:
Focuses: Cc:


The creation of a draft with post_name set to as an existing post will prevent the reachability of the older until the pubblication of the new one. The cause of the issue is that the function wp_unique_post_slug only acts if the post isn't in the status of draft or pending so in the database will be stored two posts with the same post_name. In the frontend side (in a installation with permastruct set to /%postname%/) the executed query is

SELECT wp_posts.* FROM wp_posts WHERE 1=1 AND wp_posts.post_name = 'example' AND wp_posts.post_type = 'post' ORDER BY wp_posts.post_date DESC

This query will return 2 posts and the wordpress considers the most recent (the draft) so the url returns 404.

Change History (2)

#1 @uatania
4 years ago

Waiting for a fix I added the code below for filter the posts returned by the main query and giving priority to the published (or older) one:


add_filter('posts_results', 'fixIfSingleHasMultiplePosts', 10, 2);
function fixIfSingleHasMultiplePosts($posts, $wp_query)
    // check if main query in single page
    if(!$wp_query->is_main_query() || !$wp_query->is_single()) {
      return $posts;

    // check bug
    $n_posts = count($posts);
    if($n_posts < 2) {
      return $posts;

    $i = 1;
    while ($i < $n_posts && isset($posts[$i])) {

      if(($posts[$i]->post_status == 'publish' && $posts[($i - 1)]->post_status != 'publish') || $posts[$i]->post_date < $posts[($i - 1)]->post_date) {
        unset($posts[($i - 1)]);


    return array_values($posts);

This ticket was mentioned in Slack in #meta by joyously. View the logs.

3 years ago

Note: See TracTickets for help on using tickets.