[Bug] Interrupted-turn resume rewinds event seqs in session log; history load fails permanently ("corrupt session log: seq gap in committed region") #5243
xiaochen42-zi
started this conversation in
General
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Environment: DSH Desktop v2.2.4 (Windows/Electron, dsh-plugin-desktop);
@deepseek-ai/dsh-session-persistence-jsonl@0.1.2-alpha.1,@deepseek-ai/dsh-session@0.1.2-alpha.1,@deepseek-ai/dsh-session-persistence@0.1.2-alpha.1.Storage:
~/.dsh/sessions/<encoded-cwd>/session-<uuid>/session.jsonl.zstd(multi-frame zstd: frame 1 = header line, following frames = event batches).Bug — seq rewind after interrupted-turn resume (100% reproducible)
When a turn is interrupted (tool timeout / hard kill / LLM stream cut), the harness first commits synthetic closers:
On resume it re-emits the stream from the old seq K, so the log contains both the stale closers and re-emitted events with overlapping seqs:
The scanner (
SessionLogScanner.consumeEventLine) requires strictly increasing seqs and throwscorrupt session log: seq gap in committed region at line N (expected X, got Y)as soon as a laterturn/endappears — the session history then fails to load forever, and only torn-tail truncation is auto-repaired (no recovery path for committed-region seq rewinds).Variant B:
agent/inbox/splicedmarker rows carry the previous event's seq (off-by-one duplicate).Measured instances (2026-08-31, 7 sessions on one machine):
fab8f155line 61 (expected 531, got 527);a30387a2line 1086 (18983 vs 18980);146002c3line 84 (1527 vs 1524);96fdda58line 112 (1354 vs 1352);6d43a2e6line 11916 (152814 vs 152813, variant B);16868eabline 126 (634 vs 633, variant B);08e27cc4/af00b3e9same pattern. Every interrupted turn re-corrupts the session.Suggested fix: truncate the synthetic closer block before resuming (or resume numbering from the in-memory event counter); fix
agent/inbox/splicedseq allocation; add a load-side repair path for "duplicate of already-stored prefix" patterns.Bug — any blank/unparsable JSONL row hard-fails history load
consumeEventLinerunsJSON.parseon every complete row and does not skip blank rows; a blank line recordscorrupt session log: unparsable committed event at line N, and any laterturn/endthrows it — the whole log is rejected although the events are present and complete. No user-facing recovery entry point exists. The reported line number shifts as the file grows, making the failure look transient.Measured on 4 sessions (e.g.
session-a30387a2-6c38-40ed-a435-cd3bebbc8d11, blank row right after aturn/end).Suggested fix: treat blank rows like torn tail (skip with a warning); offer a self-heal path for isolated unparsable rows; report byte offset / seq range instead of only the row number.
Minor: the GUI keeps showing the stale red "history load failed" banner after the log is repaired until the session is reopened.
All affected sessions were recovered locally (dropping the stale closer block / the blank row; backups kept as
session.jsonl.zstd.bak-2026*). Happy to share sanitized samples and recovery scripts on request.All reactions