I think the reason for this is the
get_page_by_path() check inside the
WP_Query, because it's checking for both
attachment slugs, in this case.
So if we have both an attachment and a post with the
someslug postname and visit:
get_page_by_path() will generate the following query:
SELECT ID, post_name, post_parent, post_type
WHERE post_name IN ('someslug')
AND post_type IN ('page','attachment')
and we're therefore served the attachment's page instead of the post's page.
So this seems to be a core feature but not a bug generated by your plugins.
Because of the permalink settings, the post request is handled like a page request.
We therefore have the
pagename query variable constructed instead of the
name query variable.
We can adjust the query variables, generated for the post request:
* Handle post requests correctly, in the case of the /%postname%/ permalink settings
! is_admin() && add_filter( 'request', function( $query_vars )
isset( $query_vars['pagename'] )
&& $post = get_page_by_path( $query_vars['pagename'], OBJECT, 'post' )
if( is_a( $post, '\WP_Post' ) )
// Add the 'name' query variable
$query_vars['name'] = $post->post_name;
// Unset the 'pagename' query variable
unset( $query_vars['pagename'] );
}, PHP_INT_MAX );
Here we check if a post exists with the
pagename slug and if it exists, we construct the
name query variable and finally unset the
pagename query variable.
Now the post should be served instead of the attachment.