Skip to content

Thinking Mode 400 Error — DeepSeek Harness Guide

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 be
passed 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.

A session that has already hit this can’t be recovered from the outside. What’s left:

  • Avoid it: keep reasoningEffort at off for 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:
    ...toolCalls.length > 0 ? { reasoning_content: reasoning } : {},
    The thread verified that this returns 200 OK with an empty-string reasoning_content. It’s a community patch. Nothing had merged upstream as of this Discussion.

Discussion #739 — 思考模式下工具调用返回 400 INVALID_REQUEST — reasoning_content 未回传