Skip to content

fix: auto-submit silently drops a change made during a follow-up submit - #102

Merged
lucas-barake merged 2 commits into
mainfrom
fix/autosubmit-pending-change-lost
Jul 10, 2026
Merged

fix: auto-submit silently drops a change made during a follow-up submit#102
lucas-barake merged 2 commits into
mainfrom
fix/autosubmit-pending-change-lost

Conversation

@lucas-barake

Copy link
Copy Markdown
Owner

Summary

High-severity lost-update in autoSubmitAtom (onChange + autoSubmit, no debounce), found in a deep review with executed Red→Green validation.

When a submit completes with pendingChanges queued, the follow-up get.set(submitAtom) runs synchronously and the batch commit re-enters the submitAtom subscription in place. The re-entrant invocation correctly sets wasSubmitting = true, but control then returns to the outer callback whose trailing wasSubmitting = isSubmitting still holds the stale false — clobbering it. From then on the tracker believes no submit is in flight, so when the follow-up submit completes, the wasSubmitting && !isSubmitting guard fails and any change queued during it is silently never submitted (stale server state).

Interleaving: submit A in flight → edit "c" queued → A completes → follow-up B("c") fires and corrupts the flag → edit "d" queued during B → B completes → guard false → "d" never submits.

Re-entry mechanics verified in the installed effect source (batch write/refresh: Atom.ts:1244-1253; synchronous listener notify in commit: AtomRegistry.ts:1069-1073).

Fix

Assign wasSubmitting before triggering the follow-up submit, so the re-entrant waiting=true assignment is the last write.

Tests

New regression test drives the exact interleaving with gated Effect.callback submits: Red on unmodified code (expected [ 'b', 'c' ] to deeply equal [ 'b', 'c', 'd' ]), Green after. Full suite 302 passed, types + lint clean. Independently re-validated (Red re-confirmed on clean main before applying the fix).

When a submit completes with pendingChanges queued and no debounce is
configured, the follow-up get.set(submitAtom) synchronously re-enters the
submitAtom subscription (batch commit notifies listeners in place). The
re-entrant call sets wasSubmitting = true, but the outer callback then ran
its trailing wasSubmitting = isSubmitting with the stale false, clobbering
it. The next completion failed the wasSubmitting guard and the queued
change was silently dropped. Assign wasSubmitting before triggering the
follow-up submit.
@lucas-barake
lucas-barake merged commit 1f9b932 into main Jul 10, 2026
4 checks passed
@lucas-barake
lucas-barake deleted the fix/autosubmit-pending-change-lost branch July 10, 2026 02:35
@github-actions github-actions Bot mentioned this pull request Jul 10, 2026
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.

1 participant