This troubleshooting indeed took me a while to even understand why this could happen. The symptom is pretty simple: when trying to access a new post, you are redirected to another (old) post. Sounds strange, here is how to recreate it.
Let’s start with a fresh WordPress installation, where there is only one post called “Hello World”. Now, let’s do some experiment:
- Change the title of the post to “Hello WordPress”, also, change the post name (slug) from “hello-world” to “hello-worldpress”.
- Open a web browser, access the test site by going to the “Hello WorldPress” post. You will soon find out, the exact same post can be reached via both permalink:
http://testsite.com/hello-wordpress, and http://testsite.com/hello-world.
- Next, let’s create a new post called “Hello World”, and paste some Ipsum dummy content. When we save the post, it should have a post name (slug) “hello-world” assigned by WordPress by default.
- Now, if we try to access the new page by going to http://testsite.com/hello-world, it doesn’t bring up the new post just created in step 3. Instead, we are redirected to the old “Hello World” post which has been renamed to “Hello WordPress” at step 1.
After further research, I realized that it is a bug existing in WordPress version 4.4 (or earlier?)., and is reported to be fixed in 4.4.1. Before we can lay our hands on the updated version, let’s fix the problem.
When renaming a post name (slug) of a post, WordPress records the current post name to a post meta called “_wp_old_slug”. In case user reaches the post by the old slug, WP redirects to the post by reading the _wp_old_slug meta value. It serves the similar purpose like 301 redirect. But the problem is, WP should check existing slug which has higher priority than the “_wp_old_slug”.
If you dig deeper in the database, it looks like this:
The fix is simple, click on the “Delete” button in phpmyadmin. Or for the SQL command:
DELETE FROM wp_postmeta WHERE meta_key=”_wp_old_slug” AND post_id = %id;
remember to replace “wp_postmeta” with your actual database table name, and replace “%id” with the actual value. Or, you can simplify the command to remove all the _wp_old_slug post metas:
DELETE FROM wp_postmeta WHERE meta_key=”_wp_old_slug”;
As for not-so-techy solution, here is a plugin which claims work the wonder.