livestorejs/livestore
View on GitHubBoot: schema‑mismatch event payloads trigger Die and stop backend pulling
Open
#732 opened on Oct 7, 2025
bugerror-handlinghelp wantedsyncingtestingtype:bug
Repository metrics
- Stars
- (3,599 stars)
- PR merge metrics
- (PR metrics pending)
Description
Boot: schema‑mismatch event payloads trigger Die and stop backend pulling
Summary
- When the sync backend delivers an event whose args don’t match the event’s schema, a ParseError bubbles up as a Defect (Die). During boot this occurs inside the backend‑pulling fiber and results in the fiber terminating. The log shows “Ignoring sync error (Die)”, but pulling then stops, potentially stalling boot.
Evidence
- Runtime log excerpt:
- DEBUG: “Ignoring sync error (Die)” followed by ParseError for invalid field:
- Expected number, actual null for
issueId
- Expected number, actual null for
- DEBUG: “Ignoring sync error (Die)” followed by ParseError for invalid field:
- Relevant code paths:
- packages/@livestore/common/src/materializer-helper.ts:38 (Schema.decodeUnknownSync in getExecStatementsFromMaterializer)
- packages/@livestore/common/src/materializer-helper.ts:102 (dev-only hash via makeMaterializerHash)
- packages/@livestore/common/src/leader-thread/LeaderSyncProcessor.ts:774 (computing materializerHashLeader inside pull tap)
- packages/@livestore/common/src/leader-thread/materialize-event.ts:65 (non-dev materialization also decodes args)
- packages/@livestore/common/src/leader-thread/LeaderSyncProcessor.ts:262 (catch-all cause handler logs and returns)
Observed Behavior
- Malformed event payload → Schema.decodeUnknownSync throws → effect dies in backend‑pulling tap → handler logs and returns → pulling fiber terminates → no further upstream progress; boot may not complete.
Real-World Trigger
- Example app events enforce numeric fields (e.g. issueId). If upstream sends
nullfor a numeric field, decoding fails.
Reproduction (tests)
- Location: tests/package-common/src/leader-thread/malformed-events.test.ts
- Steps:
- Start leader with default onSyncError: 'ignore' and live pull.
- Mock backend: advance a malformed event (e.g., name matches schema but a numeric field is null).
- Then advance a valid event.
- Current behavior: logs include “Ignoring sync error (Die)”; subsequent valid event is not processed (pulling stalled).
- Expected behavior: no Die; pulling stays alive; subsequent valid event is processed.
Impact
- Boot reliability: initial sync can stall.
- Sync robustness: a single malformed event terminates pulling.
- Developer experience: dev-only hash path surfaces earlier, but same failure possible at materialization.
Expected Behavior
- Malformed event payloads are handled intentionally without unhandled defects.
- With onSyncError: 'ignore', log a structured, expected error and continue pulling.
- Boot completes; subsequent valid events are processed.
Acceptance Criteria
- Reproduced failure covered by a test under tests/package-common/src/leader-thread.
- Schema mismatch does not terminate backend pulling.
- Error surfaced as expected, structured error (not a Defect), with clear context.
- Boot proceeds and sync continues with subsequent valid events.
Filed by an assistant on behalf of the user.