Skip to content

Fix mask resurrecting key in object when it is cleared#4812

Open
danharrin wants to merge 1 commit intoalpinejs:mainfrom
danharrin:fix/mask-resurrecting-key-in-object
Open

Fix mask resurrecting key in object when it is cleared#4812
danharrin wants to merge 1 commit intoalpinejs:mainfrom
danharrin:fix/mask-resurrecting-key-in-object

Conversation

@danharrin
Copy link
Copy Markdown
Contributor

@danharrin danharrin commented Apr 11, 2026

When a reactive object is cleared (e.g. form = {}), Alpine's x-model effect fires _x_forceModelUpdate(undefined) on inputs still connected to the DOM. The mask plugin's wrapper around this function converts undefined to the string "undefined" via String(value), formats it to "", then calls el._x_model.set('') — which evaluates form.amount = '', resurrecting the deleted key with an empty value. In a Livewire context, this stale key gets sent back with the next server request, corrupting server-side state.

Steps to reproduce:

  • Have an input with x-model="form.amount" and x-mask:dynamic="$money($input)"
  • Set form.amount to a value (e.g. '5000')
  • Clear the parent object: form = {}
  • Observe that form.amount reappears as an empty string

Findings

The mask plugin wraps _x_forceModelUpdate (defined in x-model.js) to apply formatting before updating the DOM. The original function already handles undefined correctly for nested model paths (converts to '' and updates the input). The issue is that the mask wrapper runs String(value) and el._x_model.set(value) unconditionally — even when the value is undefined because the model path no longer exists.

Proposed solution

Add an early return in the mask wrapper when value === undefined. This skips the formatting/write-back path entirely and delegates to the original _x_forceModelUpdate, which already handles undefined properly. Crucially, el._x_model.set() is not called, so the deleted key is not recreated.

@danharrin danharrin marked this pull request as ready for review April 12, 2026 09:07
@joshhanley joshhanley changed the title fix: Mask resurrecting key in object when it is cleared Fix mask resurrecting key in object when it is cleared Apr 13, 2026
@ekwoka
Copy link
Copy Markdown
Contributor

ekwoka commented Apr 13, 2026

Why is this the way you want to clear the form state?

Can you not use form.reset()?

@danharrin
Copy link
Copy Markdown
Contributor Author

This is not for clearing form state, this is part of a larger system that manages nested modal stacks that can contain forms.

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.

2 participants