Session log corrupt after interrupted tool call + restart: seq overlap in committed region #2839
Replies: 1 comment
|
Great report — complete repro path, log evidence, and a working manual fix. I traced the mechanism through the rc.7 source ( 1. The normal seed path cannot produce your overlap. On restart, 2. So the overlap means the resume seed EXCLUDED the placeholder block while the file retained it. The only mechanism that fits: the resumed session was prepared from a stale prepared source — the 3. Your manual fix (drop the placeholder block) is the correct recovery, and it maps to a durable invariant. The placeholders are entirely redundant once the replay has produced real events — they were only needed to keep the crash tail balanced until the turn could be replayed. The loader's 4. Concrete fix directions (any subset):
5. Impact note: this is the 8th corruption-family report (mechanisms across #1333/#1452/#1497/#1473/#1586/#2167/#2342), and the first one on rc.7. It's a resume-path coherence bug rather than a crash-durability bug — which is why it survives the recent durability hardening (zoahdev's #2342 fixes targeted the cold-load liveness and synthetic-tail paths, not the prepared-source staleness window). Worth elevating: "interrupt then restart" is a very common user action. Thanks for the decoded log evidence — it made the mechanism unambiguous. |
Uh oh!
There was an error while loading. Please reload this page.
Summary
Session history becomes unloadable (
history unavailable) after an interrupted tool call followed by a restart: the session log gets two event blocks with overlappingseqvalues (old "interrupted" placeholder events + replayed real events), and the loader rejects it as a corrupt log.Environment
0.1.0-rc.7, web profile, Windows 11, Node 26dsh webrun (no custom patches)Error
Reproduction path
tool/result×2 withmessage.id=interrupted-tool-result-...(seq N, N+1)step/end(seq N+2),turn/endwithreason: "interrupted"(seq N+3),session/end-seed(seq N+4)dsh web; the session resumes and replays from the last checkpoint. Replay re-runs the interrupted step and appends the realtool/result/tool/callevents — withseqre-allocated starting again at N.expected 34898, got 34893), and marks the log corrupt.Log evidence (decoded from session.jsonl.zstd)
Impact
Suggested fix
When resuming/replaying after an interruption, the write watermark should resume from the last seq of the committed region (skipping the interrupted placeholder events), or the replay should first truncate/overwrite the placeholder block so no seq range is written twice.
Manual workaround used: decode the zstd log, drop the 5 placeholder lines whose seq range overlaps the replayed block, re-encode — history loads again.
All reactions