[4.x] Fix mergeNewSnapshot corrupting ephemeral data when array keys contain dots#10029
Merged
calebporzio merged 9 commits intomainfrom Mar 17, 2026
Merged
Conversation
…ng-keys-snapshot-merge
When existing keys shift position in an object (e.g. a key inserted in the middle), patching key-by-key appends new keys at the end. Detect this and replace all keys on the target to preserve the correct order.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The Scenario
When a component uses PHP array keys that contain dots, the second interaction with the component throws an error. The first click works fine, but any subsequent request fails with "Undefined array key":
The Problem
The
mergeNewSnapshotmethod injs/component.jsapplies server changes to the client's reactive state usingdataGet/dataSetwith dot-notated path strings:When the
diff()function encounters an array key likeorder.foo.bar, it builds a path string"articles.order.foo.bar".dataGetanddataSetthen split this on ALL dots, interpreting it as 4 nested levels (articles→order→foo→bar) instead of 2 levels (articles→order.foo.bar).This corrupts
this.ephemeral/this.reactiveby creating spurious nested objects, causing subsequent requests to send malformed data to the server.The Solution
Replaced the flat-diff +
dataGet/dataSetapproach with a recursive tree-walking function (applyServerChanges) that compares old and new server state and applies differences directly viaobj[key]access — never constructing or parsing dot-notated path strings.The new approach achieves the same granularity as the previous implementation (only updating properties the server actually changed, preserving client-side ephemeral state) while correctly handling keys that contain dots.
Fixes #10026