Replies: 1 comment
|
Recurrence confirmed (2026-08-14, same session, same pattern).
Trigger analysis for this occurrence: the agent ran a long-running tool ( Observation that may help the fix: the interrupted-tool-result closer's Local recovery applied again: dropped the 4 synthetic closer rows; stream contiguous 0..472726 (472 727 events); verified through the real backend read path and live session.history RPC. |
Uh oh!
There was an error while loading. Please reload this page.
Bug report:
corrupt session log: seq gap in committed region— duplicated seqs when two dsh processes write the same session (interrupted-turn closers race live resume appends)Reported via GitHub Discussions per the README/CONTRIBUTING (the repository has Issues disabled).
Environment
@deepseek-ai/dsh0.1.0-rc.6 (npm global install; monorepo dirapps/cli)@deepseek-ai/dsh-session-persistence-jsonl0.1.0-rc.6 (dirpackages/session/session-persistence-jsonl)session.jsonl.zstd(zstd frames,packChunkson)Symptom
History load fails in the Web UI:
Thrown by
SessionLogScanner.consumeEventLine(packages/session/session-persistence-jsonl/lib/index.js, ~line 275-300): every stored event'sseqmust equal the running event count; the log is otherwise rejected (or degraded to a truncated prefix, unless aturn/endrow is involved, in which case it throws).Root cause
The JSONL backend serializes per-session-id writes only within one process (
PersistenceCoordinator.serialize,packages/session/session-persistence/lib/index.js~line 1079;appendCore~line 829 validatesevent.seq === state.cursor + i). There is no cross-process coordination (no file lock, no revision compare-and-swap before append). Normal usage — thedsh webserver and a CLI session both opening/resuming the same conversation — lets two processes hold independent in-memory cursors for the same log:tool/call, seq N-1).prepareCore→interruptedTurnClosers()(packages/session/dsh-session/lib/index.jsline 626) and durably commits 4 synthetic closers viacommitRepair:tool/result(message idinterrupted-tool-result-<callId>-<seq>),step/end,turn/end(reasoninterrupted),session/end-seed, with seqs N..N+3.Observed file layout (decoded from the artifact)
The identical pattern hit a second session (line 4815, expected 74251, got 74247).
Why this cannot happen in a single process
prepare()throwscannot prepare session ... while it is live(dsh-session-persistence ~line 852), so closers cannot be committed over a live session.append seq mismatch(~line 835) and surface as a background-write failure, not a silent duplicate.Two independent cursors for one log therefore require two processes. (Observed: several node processes were running at corruption time; after restart only one dsh process remains, and both sessions resumed with fully contiguous appends — no recurrence in the single-process path.)
Impact
Suggested fixes (any one would close this)
commitRepair/closer synthesis conditional on the log still ending at the same revision (do not commit closers over a log that has grown since it was read).Local recovery applied (informational)
The 4 synthetic closer rows were removed per session (originals backed up); streams are strictly contiguous again (295 839 and 123 491 events), verified through the real backend read path, the
Sessionstate-machine validation, and a livesession.historyRPC (ok: true). Both sessions have since resumed and appended thousands of events with contiguous seqs. Happy to share the repair script or any further evidence if useful.All reactions