Make WordPress Core

Opened 2 years ago

Last modified 9 days ago

#24612 accepted defect (bug)

Permalink conflict: image attachment page and post when permalink setting is /%postname%/

Reported by: augustas Owned by: SergeyBiryukov
Milestone: 4.4 Priority: normal
Severity: normal Version: 3.3
Component: Permalinks Keywords: needs-unit-tests 4.4-early needs-patch
Focuses: Cc:


Here is scenario when there is a permalink conflict between the "attachment page" URL and post when image filename and post name are equal:
Permalinks are set to /%postname%/

Using Media -> Library -> upload new image called about-me.jpg
System saves into "wp_posts" database table: post_name = "about-me"

I publish a new POST with the title "About Me". For this post database stores the post_name = "about-me"

If I go to URL: www.example.com/about-me/ - I am redirected to about-me.jpg Image Attachment Page.

If POST is created first and the image uploaded second - URL will open the POST.

This issue is similar to #13459

Attachments (1)

24612.patch (1.2 KB) - added by SergeyBiryukov 20 months ago.

Download all attachments as: .zip

Change History (15)

comment:1 @augustas2 years ago

  • Summary changed from Permalink conflict when image is not attached to the post and permalink setting is /%postname%/ to Permalink conflict: image attachment page and post when permalink setting is /%postname%/

comment:2 @SergeyBiryukov2 years ago

  • Milestone Awaiting Review deleted
  • Resolution set to duplicate
  • Status changed from new to closed

comment:3 @SergeyBiryukov20 months ago

  • Milestone set to Awaiting Review
  • Resolution duplicate deleted
  • Status changed from closed to reopened

Reopening per ticket:15665:28, as #15665 only covered pages.

comment:4 @aaroncampbell20 months ago

I ran into this yesterday. I definitely think that posts should take precedence over attachments in this case. Especially since the UI to change media slugs is hidden in screen options by default.

@SergeyBiryukov20 months ago

comment:5 @SergeyBiryukov20 months ago

  • Keywords has-patch needs-unit-tests added
  • Version changed from 3.5.1 to 3.3

Introduced in [18541], specifically with the changes in WP_Rewrite::page_rewrite_rules().

24612.patch fixes it for me.

Last edited 20 months ago by SergeyBiryukov (previous) (diff)

comment:6 @aaroncampbell20 months ago

24612.patch works for me. It's very specific to "post" though. Do we want to assume that handling slug conflicts for custom post types should be done in the plugin that creates the post type?

Last edited 6 months ago by SergeyBiryukov (previous) (diff)

comment:7 @SergeyBiryukov6 months ago

A workaround:

function wp24612_resolve_post_vs_attachment_permalink_conflict( $query ) {
	if ( is_admin() || ! $query->is_main_query() ) {

	if ( ! preg_match( "/^[^%]*%(?:postname)%/", get_option( 'permalink_structure' ) ) ) {

	if ( empty( $query->queried_object ) || '' === $query->get( 'pagename' ) ) {

	if ( 'attachment' === $query->queried_object->post_type ) {
		// See if we also have a post with the same slug
		$post = get_page_by_path( $query->get( 'pagename' ), OBJECT, 'post' );
		if ( $post ) {
			$query->queried_object    = $post;
			$query->queried_object_id = (int) $post->ID;
			$query->is_page           = false;
			$query->is_single         = true;
add_action( 'parse_query', 'wp24612_resolve_post_vs_attachment_permalink_conflict' );

comment:8 @dmchale3 months ago

Thanks for that workaround @SergeyBirukov it worked perfectly on one of my client sites. (the latest patch did not. I tried to update query.php with the code changes in that patch manually, just to see if it was viable, but it seems the fact that the code did not set queried_object_id or is_single was causing problems)

Unfortunately, this issue has bitten me TWICE in the past 2 weeks at my day job, after 3 years of never having knowingly run into it before. I think a good part of the trouble stems from our SEO department wanting to ensure that all of our file names are now "search engine friendly" and as such have been trying to name documents and images more intelligently now on our client sites. Due to this, they HAPPEN to be naming some images/files the same as other objects within the system and it's causing issues when all of a sudden a section of the website "disappears" and site visitors are redirected to a PDF file rather than the content they were supposed to be served.

I did a bit of testing at home on my VVV setup tonight, and documented some of my steps and my findings as I went. I would love to help talk through a workaround that could be implemented in core, if possible. Since I don't have any history with how/why things were made getting to this point, I'm not sure why some design decisions were made. I did go through all of the tickets referenced by this ticket though, so I have at least read up a good deal on some others' issues with dealing with the same thing.

My notes are below..... apologies for length, I tried to be thorough.

start with clean install of trunk
set permalinks to /%post-name%/

created "Permalink" PAGE (system gave it a slug of /permalink/)
created "Permalink" POST (system gave it a slug of /permalink/)

Already have a conflict. Why can POSTS create a shared slug as PAGES?

uploaded permalink.pdf (system gave it a slug of /permalink-2/)

  • Side note, the "permalink" shown at the top of the page still shows the native /attachment_id=N format, which obviously does not match my permalink setting. Is this by design, or something that should be addressed? It's misleading at best.

View /permalink/, system displays the PAGE content
Edit PAGE, update permalink to /permalink-page/

Refresh /permalink/, system now displays the POST content

  • While a PAGE and POST existed with the name conflict, the PAGE always "won"

Edit POST, update permalink to /permalink-post/

Refresh /permalink/, WP now redirects to /permalink-post/

Upload permalink-post.pdf (system gave it a slug of /permalink-post-2/)
No conflict!

<Conclusion: you cannot create a slug conflict by uploading media files after an existing post type "owns" the slug> ..... Challenge: Is this true for all post types, CPTs included, or only pages/posts? Need to test.

Upload permalink-file.pdf (system gave it a slug of /permalink-file/)
Create POST called "permalink file" (system gave it a slug of /permalink-file/)
Viewed /permalink-file/, system shows the media page with a link to download the PDF

<Conclusion: you CAN create a post that will cause a naming conflict with a pre-existing media library item (as well as PAGE)>

Deleted "permalink file" POST, removed it from trash

Create PAGE called "permalink file" (system gave it a slug of /permalink-file-2/)
No conflicts!

<Conclusion: Add New Page behavior respects `attachment` post types, while Add New Post does not>


  • It is currently impossible to create a naming conflict between pages/attachments. No matter which you create first, the second one will pick a unique slug.
  • Add/Edit Post should be updated to mimic Add New Page functionality, at least in regards to preventing naming conflicts with attachment post types.
  • Permalinks/slugs have been demoted in the media library to the point of obvious confusion.
  • - The current behavior of the system to use the slug as a permalink, but never SAYS this is the case. This seems to be a massive UI failure.
  • - Slug editing is disabled from Screen Options by default, which makes things even more challenging to troubleshoot in this scenario
  • Would suggest that "Permalinks" on the media edit page be updated to behave the same way pages/posts do, so the slug can be modified in place at the end of the url.
  • - The screen could also CONTINUE to show the permanent link to the /?attachment_id=N url as well below, which would remain unchangeable.
  • Bottom line, my belief is that the post/page/attachment post types should all respect each other out of the box and never create naming conflicts with each other. The matter of whether this is done ONLY when WP is set to /%post-name%/ setting, or always, can easily be a talking point. If naming conflicts were created because of/during the changing of the permalink setting, that's something a site admin could/would/(should?) have to address at that time. That job could even be plugin territory, an opportunity for someone to write a tool that would address that for people.

comment:9 @SergeyBiryukov2 months ago

  • Keywords 4.4-early added
  • Milestone changed from Awaiting Review to Future Release

comment:10 @SergeyBiryukov2 months ago

  • Owner set to SergeyBiryukov
  • Status changed from reopened to accepted

comment:11 @SergeyBiryukov7 weeks ago

  • Milestone changed from Future Release to 4.4

comment:13 @slackbot9 days ago

This ticket was mentioned in Slack in #core by sergey. View the logs.

comment:14 @SergeyBiryukov9 days ago

  • Keywords needs-patch added; has-patch removed
Note: See TracTickets for help on using tickets.