[Bug] Tool-call name dropped when gateway streams explicit "null" name deltas (dsh-llm-deepseek) #2997
Replies: 2 comments
|
Verified against rc.7 ( 1. Confirmed at source.
2. Your fix is incomplete — if (typeof call.id === 'string' && call.id.length > 0) block.callId = call.id
if (typeof call.function?.name === 'string' && call.function.name.length > 0) block.name = call.function.name3. The design intent is "first non-null wins" — and the assembler already implements it for name but not id. 4. One more surface in the same delta emission. 5. Family connection. This is a new trigger class in the serializer/wire family (the "explicit-null-overwrite" class, complementing the lone-surrogate/malformed-arguments poisoning class): the same Good catch — and thanks for including the raw deltas; that's what made it verifiable in one pass. |
|
Correction/addendum to my comment above — this is actually the third independent report of this exact mechanism, not a new class: #1713 (BehindTheCartan, SGLang endpoint) and #2090 (Xreative, another gateway) documented the identical explicit- For convergence: #1713's analysis already included the |
Uh oh!
There was an error while loading. Please reload this page.
Bug: Tool-call
nameis dropped when the provider streams explicit"name": nulldeltasSummary
When using an OpenAI-compatible gateway (not the official
api.deepseek.com) asllm-deepseek.baseURL, every tool call loses its function name (namebecomes empty). The harness then fails every tool invocation withError: unknown tool "", and agents loop/retry until they exhaust. Simple no-tool conversations work fine.Environment
@deepseek-ai/dsh0.1.0-rc.6 (also verified on 0.1.0-rc.7 — same code path)@deepseek-ai/dsh-llm-deepseekdeepseek-v4-flash(also observable withdeepseek-v4-pro)https://opencode.ai/zen/go/v1(OpenAI-compatible chat/completions), streaming withstream_options.include_usage=trueRepro
llm-deepseek.baseURLto any OpenAI-compatible gateway that emits the standard streaming shape shown below.name: ""and the tool layer returnsError: unknown tool "". The model retries and typically fails the whole task.Root cause
In
@deepseek-ai/dsh-llm-deepseek/lib/index.js(translate), the tool-call name is applied with:In JavaScript,
null !== void 0evaluates totrue. OpenAI-compatible gateways emit the first streaming delta with the real name, then subsequent deltas with explicitnullforid/name(standard shape). Those subsequent deltas overwrite the captured name withnull, andcloseBlockthen flattens it to"".The official DeepSeek API does not send the explicit
null(it omits the fields entirely), so this bug is invisible againstapi.deepseek.comand only appears when a gateway sends the protocol-standardnull.Wire evidence
Streaming deltas received from the gateway (real trace):
After the patch below, the same task succeeds:
name: "glob", output completed with correct file count.Suggested fix
Only overwrite when
nameis a non-empty string:Equivalent guards are used elsewhere in the file for
call.idand forreasoning_content/content. The same!== void 0pattern on a nullable field is a latent bug for any gateway that serializes nulls.Notes
dsh-llm-deepseekfor both the web and headless profiles.All reactions