WordPress.org

Make WordPress Core

Opened 4 years ago

Last modified 4 months ago

#43122 assigned defect (bug)

customize.php fails to load with default changeset_uuid

Reported by: bpayton Owned by: bpayton
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 4.7
Component: Customize Keywords: needs-patch reporter-feedback
Focuses: Cc:

Description

I am seeing a rare condition where users are unable to load the Customizer with no specified changeset and see the message "Cheatin, uh? This changeset cannot be further modified."

In all cases, I am seeing two customize_changeset posts with the same GUID post name, one with draft status and the other with published status. When WP_Customize_Manager attempts to find a changeset to load by default, it finds the draft with the GUID, and when it attempts to load the post, it finds the published post with the same GUID and dies with the message mentioned above.

I read WP_Customizer and theorized how this could be happening but have no theory worth mentioning. Still, this seems like some kind of race condition.

Change History (6)

#1 @bpayton
4 years ago

@westonruter, off the top of your head, do you have any idea why something like this might be happening?

#2 @westonruter
4 years ago

  • Version changed from 4.9 to 4.7

@bpayton sorry for the delay. Interesting. So you see two separate customize_changeset posts in the DB with the same UUID post_name? It has an actual status of publish or is it trash in this case because it was published and thus advanced for garbage collection? Are you seeing this happen on WordPress.com? It could be due to latency in DB replication.

In particular, note that \WP_Customize_Manager::find_changeset_post_id() saves the located changeset post ID in the object cache, using the UUID as the key. If you then look at \WP_Customize_Manager::save_changeset_post() when it goes to insert a new changeset, you can see that it does wp_insert_post() but then immediately after it does not do wp_cache_set( $uuid, $changeset_post_id, $cache_group ) like \WP_Customize_Manager::find_changeset_post_id() does. This means that potentially the DB write happens but there is a latency for the replication to happen, and then immediately after another call to \WP_Customize_Manager::find_changeset_post_id() is made and since the object cache has not been populated with the changeset's ID, it tries to do a query to find the post but it comes up empty because it hasn't propagated yet.

If merely the object cache were updated with the UUID/post_id mapping it wouldn't be enough since the DB would not have the post in it yet, so perhaps in addition to preemptively setting the object cache with the UUID/post_id mapping the actual WP_Post for the newly-inserted customize_changeset should be preemptively cached via update_post_cache( array( $post ) ) as well?

This ticket was mentioned in Slack in #core-customize by bpayton. View the logs.


4 years ago

#4 @westonruter
4 years ago

  • Owner set to bpayton
  • Status changed from new to assigned

#5 @mermel
3 years ago

Wanted to add that we're still seeing this issue for WPCOM customers. In the most recent case there were 3 customize_changeset posts (draft, publish, and auto-draft in the DB with the same post_name.

#6 @celloexpressions
4 months ago

  • Keywords needs-patch reporter-feedback added

Is anyone able to reproduce this issue outside of the WordPress.com environment? It sounds like something may be happening there that allows duplicate changeset post_names.

Core could do a couple of things to attempt to address this possibility:

  1. Add additional validation when saving/changing changeset post statuses to avoid creating duplicates.
  2. Attempt to locate and remove duplicated changeset posts with different statuses on load.

Those strategies may not fix the WP.com issues, though.

Note: See TracTickets for help on using tickets.