Replies: 3 comments
|
Really well-documented report — thank you for the decoded evidence and the exact repair procedure. I verified the three stacked root causes against the current source (dsh v0.1.3-alpha.1 / master 1. The harness's own pi-ai adapter does no empty-text-block filtering. 2. 3. The empty block's origin is the provider chunk stream. A community-side safety net: I shipped a plugin that audits stored session logs for exactly this class of hard-fail-before-replay — @argszero/cordis-plugin-session-audit (v0.1.2). It already detects One note for your report: the empty-block filter (fix #1) is by far the highest-value change because it solves both error variants at once AND is provider-neutral, so it'd help beyond just Claude. If you have the redacted repaired-vs-original pair handy, that's a solid regression fixture once the in-tree filter lands. |
|
Increment shipped: |
|
Confirmed working end-to-end — thanks for shipping Ran v0.1.3 (the
Also gives a useful regression datapoint: your Both sessions are now replay-safe for strict providers (Claude). Thanks again for the tooling — the pre-flight check is exactly what would have caught this before the model switch. |
Uh oh!
There was an error while loading. Please reload this page.
Environment: DeepSeek Harness 0.1.1-rc.2, Windows 11, session store
session.jsonl.zstdSummary
Sessions that ran on
google-antigravity/antigravity-gemini-3.1-proaccumulateempty text blocks (
{"type":"text","text":""}) in persisted assistant messagesreasoning + tool-call + text(""). Theseblocks are harmless under lenient models (GLM / Gemini accept them), but the
moment the session's model is switched to a Claude model, every subsequent
request fails with HTTP 400 and the session is permanently unusable - Claude's
API rejects empty text content blocks, and DSH additionally stamps
cache_controlon the trailing text block, which Anthropic also rejects.Re-login / re-auth cannot help: the poison is the stored history, not auth.
The session file also stops growing (each turn fails before anything new is
persisted), so DSH's own compaction can't recover it either - the compaction
request itself fails with the same 400.
Steps to reproduce
google-antigravity/antigravity-gemini-3.1-proand do agentic work that triggers tool calls (each tool-call turn persists
one empty text block).
claude-opus-5in our case).Observed errors (both variants seen)
Evidence (from decoding our session store)
Session with 65 persisted assistant messages produced by antigravity:
reasoning + tool-call + text(EMPTY)tool-call + text(EMPTY)Zero
cache_controlis persisted in the store - it is stamped at requestbuild time onto the trailing text block, which is how the empty block also
trips Anthropic's
cache_control cannot be set for empty text blocksrule.Root cause (three stacked issues)
text blocks are never valid for Anthropic (and questionable for any
provider); the builder should filter them out of the outgoing
messagesarray regardless of what the provider adapter persisted.
cache_controlstamping doesn't check the target block. The prompt-cachemarker is attached to the trailing text block without verifying it is
non-empty, producing the second (double) failure mode.
session to a new provider sends the old provider's raw block shapes to a
new API with different invariants. There is no normalization step between
"user picked a new model" and "replay the entire history at it".
Suggested fixes
request builder (cheapest fix, solves both error variants at once).
cache_controlstamp: skip blocks with empty text.the target provider before replaying - at minimum, the empty-text-block
filter above.
blocks in the first place.
Workaround that unblocked us (for anyone else hitting this)
Decode
session.jsonl.zstd(multi-frame zstd, frame-split on the28 b5 2f fdmagic), removecontentblocks wheretype === "text" && text.trim() === ""fromassistant/messageevents(leave
assistant/chunkstream telemetry alone), re-encode, verify roundtrip,swap back in with a backup. Our repair: 60 blocks removed from 60 messages,
922/982 events byte-identical, session worked again after reopening.
Huge thanks for a great tool - happy to provide the repaired-vs-original
session file pair (redacted) or the exact repair script if useful.
All reactions