tool/result events with empty callId cause SessionPersistenceCorruptionError on resume #4385
zhangsheng377
started this conversation in
General
Replies: 1 comment
|
和 #4240 / #4387 同一条: dsh-session-surgeon 现在不会给空 callId 编 UUID(会把后续 tool 对账修假)。 dsh plugin --profile web add "github:xiaoshenming/dsh-session-surgeon#main"空 callId 还得官方写路径拒绝空 id,或提供正式修复口。 |
0 replies
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.
Bug Description
When resuming a session, DSH may fail with:
Investigation reveals that some
tool/resultevents havesource.callId = ""(empty string) andcontent[0].toolCallId = "", which fails the validator atdsh-session/lib/index.js:1265:All affected entries share the same pattern:
error: { name: "ToolNotFoundError", code: "UNKNOWN_TOOL" }source: { kind: "tool", callId: "" }content[0]: { type: "tool-result", toolCallId: "", isError: true }Root Cause
Two issues contribute:
Write path does not validate
callId: When aToolNotFoundErroroccurs, thetoolErrorResult()function produces a result without acallId. TheappendToolResult()→createToolResultMessage()path should propagateblock.id, but in practice thecallIdarrives as an empty string. This likely happens when the LLM outputs a tool-call block with an empty or missingidfield, and the write path accepts it without validation.Read path strictly validates: The resume validator requires
callIdto be a non-empty string, creating a write-validate gap — data that was persisted cannot be loaded back.Impact
Suggested Fix
Option A (Write-side validation): Reject or sanitize tool-call blocks with empty
idbefore persisting. Ifblock.idis empty, generate a UUID so the event chain remains valid.Option B (Read-side tolerance): When the validator encounters an empty
callIdon aToolNotFoundErrorresult, treat it as a known legacy format and fill in a syntheticcallIdinstead of rejecting the entire session.Option C (Both): Validate on write + tolerate on read for backwards compatibility with existing corrupted logs.
Workaround
I've built a repair tool that:
tool/resultentries with emptycallIdrecovered-{message.id}as thecallIdThis repairs the session enough for DSH to resume it successfully.
Environment
All reactions