Skip to content

Don't evaluate old getters when reconciling x-data - #4934

Open
ckoval7 wants to merge 1 commit into
alpinejs:mainfrom
ckoval7:fix-x-data-reconcile-getters
Open

ckoval7 wants to merge 1 commit into
alpinejs:mainfrom
ckoval7:fix-x-data-reconcile-getters

Conversation

@ckoval7

@ckoval7 ckoval7 commented Oct 16, 2026

Copy link
Copy Markdown

Fixes #4933

Since #4868, changing an element's x-data expression reuses its reactive object via reconcileData(). Getter keys were removed with delete target[key] through the reactive proxy, and the proxy's deleteProperty trap reads the old value first. That invokes the old getter with this bound to the raw data object instead of the merged scope, so parent-scope properties are undefined. If the getter throws, reconciliation aborts partway: remaining keys aren't updated and the element never gets its scope back, so new x-for clones fail with "X is not defined".

This swaps old accessors for plain undefined values on the raw object before reconciling. The proxy traps then never call an old getter or setter, but they still fire, so effects that depended on a replaced getter re-run with the new one. Plain data keys behave exactly as they did after #4868.

Tests cover the reproduction from the issue, that old getters are never invoked during reconciliation (replaced or removed), and that effects depending on a replaced getter re-run.

🤖 Generated with Claude Code

Replacing x-data reads each property's old value through the reactive proxy, so old getters ran without access to the parent scope. Swap old accessors for plain values on the raw object before reconciling, and detect accessors consistently with isAccessor().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ckoval7 ckoval7 changed the title fix(x-data): avoid evaluating old getters when reconciling data Don't evaluate old getters when reconciling x-data Oct 16, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

x-data reconciliation (#4868) evaluates old getters without parent scope; a throw leaves the component without its scope

1 participant