[Bug] History loading fails with "received more than one start Match" when tool call ids are not globally unique #3408
Replies: 1 comment
|
The rc.7 replay path supports this diagnosis. Before changing durable data, a useful proof is to group root Scoping the identity needs to be end-to-end: call and result matches must derive the same composite key, and approval/root lookup paths that only carry the bare call id need an unambiguous fallback. Regression cases should cover reuse across turns, reuse across steps in one turn, nested calls, approvals, partial history windows, and live append after replay. I added a source-pinned triage map that distinguishes this from frame and sequence corruption: https://sandbaseai.github.io/deepseek-harness-handbook/session-history-recovery.html Disclosure: independent SandBase community handbook, not official DeepSeek documentation. |
Uh oh!
There was an error while loading. Please reload this page.
[Bug] History loading fails with "received more than one start Match" when tool call ids are not globally unique
Summary
Loading a session history window that spans multiple steps/turns fails in the web client with:
The root cause is that the "tool-call" conversation context key is derived from the bare callId (
conversationContextKey("tool-call", callId)), which assumes tool call ids are globally unique within a session. This assumption does not hold when the model is served through a third-party OpenAI-compatible gateway that renumbers tool call ids per request (call_0,call_1, ...). The samecall_0then appears in multiple steps/turns, and the secondstartmatch for the same context key throws duringreplaceWindowhistory loading.Environment
@deepseek-ai/dsh0.1.0-rc.6 (verified present in rc.7 and current master as well — see below)Repro / Triggering mechanism
tool/callevents.call_0,call_1, restarting fromcall_0on every request. (OpenAI-compatible responses carryidin the tool call blocks; the gateway reuses short sequential ids instead of globally unique ones.)replaceWindowfeeds every event in the window into the conversation context engine. The secondtool/callwhosecallIdiscall_0(from a different step/turn) hitsacceptMatchwithrole: "start"for the already-started context key9:tool-callcall_0, which throws:conversation Context 9:tool-callcall_0 received more than one start Match.Note the same collision can also occur within a single turn: call ids restart per step, so
call_0legitimately repeats across steps.Affected code
packages/client/ui-conversation/src/client/conversation-nodes/tool.ts(and the same pattern inpackages/client/ui-trajectory/src/client/...):The context key is built from
idalone;tool/callevents already carryturnandstepin their data, but they are not part of the key.Suggested fix
Scope the tool-call context key by turn and step so each
(turn, step, callId)combination gets a unique context:tool/call→id:${event.data.turn}:${event.data.step}:${callId}``tool/result→ same prefix (tool/resultpairs withtool/callin the same step)The
rootToolCall(snapshot, rootCallId)helper (used by approval frames that carry only the bare callId) should fall back to scanning materialized tool-call nodes when the direct key lookup misses.We have verified this fix locally: a session with 8 turns / 80 tool calls that previously produced 78 collisions loads cleanly with 0 conflicts, and the previously failing history windows now load.
Additional note
This only manifests with endpoints that reuse tool call ids across requests. With endpoints that issue globally unique tool call ids (e.g. the official API), the bug is latent and does not surface, which is likely why it has not been observed upstream.
Happy to open a PR with the fix if that is helpful.
All reactions