Thinking Mode 400 Error — DeepSeek Harness Guide
Symptom
Section titled “Symptom”With thinking mode on (reasoningEffort: high or max), any agent turn that calls a tool (bash, fs, etc.) can fail with:
HTTP 400 INVALID_REQUEST{"error":{"message":"The `reasoning_content` in the thinking mode must bepassed back to the API.","code":"invalid_request_error"}}Once a session hits this, it’s finished. Every later turn fails at the same point with the same error. Switching reasoningEffort to off in settings.yaml doesn’t help either, because a session captures the reasoning setting when it’s created and never re-reads it. Starting a new session is the only way out.
Two people traced this independently to the same line, in serializeAssistant() (lib/index.js) in @deepseek-ai/dsh-llm-deepseek:
return { role: "assistant", content: text, ...toolCalls.length > 0 && reasoning.length > 0 ? { reasoning_content: reasoning } : {}, // <- only included when reasoning is non-empty ...toolCalls.length > 0 ? { tool_calls: toolCalls } : {}};In thinking mode, DeepSeek’s API requires reasoning_content on any assistant turn carrying tool_calls, and an empty string satisfies it. This code only attaches the field when reasoning.length > 0. So when the model emits a tool call with no reasoning text on that particular turn, the field is dropped rather than sent as "", and the API rejects the harness’s next request. By then the offending message is already in the session’s history, which is why every retry reproduces it exactly.
Solution
Section titled “Solution”A session that has already hit this can’t be recovered from the outside. What’s left:
- Avoid it: keep
reasoningEffortatofffor tool-heavy sessions until this is fixed upstream. Set it before you create the session; changing it afterwards does nothing, per the cause above. - Recover: abandon the session and start a new one.
- If you’re willing to patch locally: the reported fix drops the reasoning-length half of the condition:
The thread verified that this returns...toolCalls.length > 0 ? { reasoning_content: reasoning } : {},
200 OKwith an empty-stringreasoning_content. It’s a community patch. Nothing had merged upstream as of this Discussion.
Source
Section titled “Source”Discussion #739 — 思考模式下工具调用返回 400 INVALID_REQUEST — reasoning_content 未回传
Related errors
Section titled “Related errors”- Custom session events break session resume — another way a session’s persisted history gets stuck.
- “dsh plugin remove” leaves a broken profile — another config-state bug with no in-place recovery.
- Back to Installation if you’re still setting up.