openclaw - ✅(Solved) Fix [Bug]: DeepSeek v4-pro: 400 "reasoning_content must be passed back" with thinking=disabled [2 pull requests, 2 comments, 3 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#74374Fetched 2026-04-30 06:24:47
View on GitHub
Comments
2
Participants
3
Timeline
9
Reactions
2
Timeline (top)
cross-referenced ×3commented ×2labeled ×2referenced ×1

When using deepseek-v4-pro with thinking:disabled via extra_body, conversations intermittently fail with:

400 The reasoning_content in the thinking mode must be passed back to the API.

The error occurs because DeepSeek occasionally returns reasoning_content in its response even when thinking is disabled. OpenClaw stores this in the conversation history, and on the next request, DeepSeek rejects the payload because reasoning_content from previous messages must be passed back consistently.

Error Message

The error occurs because DeepSeek occasionally returns reasoning_content in its response even when thinking is disabled. OpenClaw stores this in the conversation history, and on the next request, DeepSeek rejects the payload because reasoning_content from previous messages must be passed back consistently. "error":"400 The reasoning_content in the thinking mode must be passed back to the API.", Restarting the gateway clears in-memory session cache and stops error recurrence until DeepSeek returns reasoning_content again.

Root Cause

The error occurs because DeepSeek occasionally returns reasoning_content in its response even when thinking is disabled. OpenClaw stores this in the conversation history, and on the next request, DeepSeek rejects the payload because reasoning_content from previous messages must be passed back consistently.

Fix Action

Fix / Workaround

Environment OpenClaw: 2026.3.28 (f9b1079) Provider: deepseek Model: deepseek-v4-pro Channel: feishu / websocket Workaround

PR fix notes

PR #74403: fix(deepseek): strip reasoning_content when extra_body disables thinking

Description (problem / solution / changelog)

Root Cause

The extra_body wrapper (createOpenAICompletionsExtraBodyWrapper) runs after the DeepSeek V4 provider wrapper. When thinkingLevel is not explicitly off/none (e.g. user sets params.thinking: false which isn't recognized as a string level), the provider wrapper backfills reasoning_content: "" on assistant messages and sets thinking: { type: "enabled" }. Then extra_body overwrites thinking to { type: "disabled" }, leaving stale reasoning_content on messages — causing DeepSeek to reject with 400.

Fix

After applying extra_body to the payload, check if the resulting thinking.type === "disabled". If so, strip reasoning_content from all messages in the payload. This ensures no provider-wrapper backfill or model-response remnant leaks into a disabled-thinking request.

Changed Files

  • src/agents/pi-embedded-runner/extra-params.ts — strip logic after Object.assign(payloadObj, extraBody)
  • src/agents/pi-embedded-runner-extraparams.test.ts — regression test

Fixes #74374

Changed files

  • src/agents/pi-embedded-runner-extraparams.test.ts (modified, +36/-0)
  • src/agents/pi-embedded-runner/extra-params.ts (modified, +17/-0)

PR #74418: fix(agents): recognize params.thinking=false and "disabled"/"none" as thinking=off

Description (problem / solution / changelog)

Summary

Fixes #74374

resolveThinkingDefault only recognized string values like "off", "low", "high", etc. for per-model params.thinking. When a user configured params.thinking: false (boolean) or params.thinking: "disabled" — both common ways to express "no thinking" — the value fell through to the model/provider default (e.g. "high" for DeepSeek v4-pro).

This caused the DeepSeek thinking stream wrapper to inject reasoning_content into assistant messages and set thinking: { type: "enabled" }. If the user also configured extra_body: { thinking: { type: "disabled" } }, the extra_body wrapper then overwrote thinking to disabled — but reasoning_content was already in the messages. DeepSeek's API rejects this inconsistent state with:

400 "reasoning_content must be passed back"

Changes

  • resolveThinkingDefault now treats false, "disabled", and "none" as "off"
  • Added 3 tests for each alias (DeepSeek v4-pro model config)

Root Cause

src/agents/model-thinking-default.ts:42-52 only matched string values against the known thinking levels. Boolean false and aliases like "disabled" / "none" were not handled, causing them to fall through to the provider default. The DeepSeek V4 wrapper (createDeepSeekV4OpenAICompatibleThinkingWrapper) already handles "none" correctly at the stream level, but it was never reached because thinkingLevel was resolved to the wrong value upstream.

Changed files

  • src/agents/model-selection.test.ts (modified, +66/-0)
  • src/agents/model-thinking-default.ts (modified, +8/-0)

Code Example

{"event":"embedded_run_agent_end","isError":true,
"error":"400 The reasoning_content in the thinking mode must be passed back to the API.",
"model":"deepseek-v4-pro","provider":"deepseek"}

Two occurrences within 4 minutes (13:05 and 13:09 UTC, 2026-04-29).
RAW_BUFFERClick to expand / collapse

Bug type

Regression (worked before, now fails)

Beta release blocker

No

Summary

When using deepseek-v4-pro with thinking:disabled via extra_body, conversations intermittently fail with:

400 The reasoning_content in the thinking mode must be passed back to the API.

The error occurs because DeepSeek occasionally returns reasoning_content in its response even when thinking is disabled. OpenClaw stores this in the conversation history, and on the next request, DeepSeek rejects the payload because reasoning_content from previous messages must be passed back consistently.

Steps to reproduce

Configure extra_body: {thinking: {type: "disabled"}} for deepseek-v4-pro Have a multi-turn conversation DeepSeek intermittently returns reasoning_content in a response The next message in the conversation fails with 400 Restarting the gateway clears the in-memory session cache and temporarily resolves it Configuration (both files have extra_body set correctly)

models.json: "id": "deepseek-v4-pro" "extra_body": {"thinking": {"type": "disabled"}}

openclaw.json (agents.defaults.models): "deepseek/deepseek-v4-pro": { "params": { "thinking": false, "extra_body": {"thinking": {"type": "disabled"}} } }

Expected behavior

OpenClaw should strip reasoning_content from assistant messages in the conversation history before sending to DeepSeek when thinking is disabled. Alternatively, detect reasoning_content in history and auto-enable thinking mode for consistency.

Actual behavior

400 The reasoning_content in the thinking mode must be passed back to the API.

OpenClaw version

OpenClaw: 2026.3.28 (f9b1079)

Operating system

Debian 12 (bookworm), kernel 5.19.17

Install method

docker

Model

deepseek-v4-pro

Provider / routing chain

deepseek

Additional provider/model setup details

No response

Logs, screenshots, and evidence

{"event":"embedded_run_agent_end","isError":true,
"error":"400 The reasoning_content in the thinking mode must be passed back to the API.",
"model":"deepseek-v4-pro","provider":"deepseek"}

Two occurrences within 4 minutes (13:05 and 13:09 UTC, 2026-04-29).

Impact and severity

No response

Additional information

Environment OpenClaw: 2026.3.28 (f9b1079) Provider: deepseek Model: deepseek-v4-pro Channel: feishu / websocket Workaround

Restarting the gateway clears in-memory session cache and stops error recurrence until DeepSeek returns reasoning_content again.

extent analysis

TL;DR

Modify OpenClaw to strip reasoning_content from conversation history when thinking is disabled to prevent 400 errors.

Guidance

  • Verify that extra_body is correctly set to {thinking: {type: "disabled"}} in both models.json and openclaw.json to ensure consistency in configuration.
  • Investigate modifying OpenClaw's conversation history handling to remove reasoning_content when thinking is disabled, or to auto-enable thinking mode when reasoning_content is detected in the history.
  • Consider implementing a temporary workaround by periodically restarting the gateway to clear the in-memory session cache, although this is not a permanent solution.
  • Review the OpenClaw version (2026.3.28) and provider/model setup to ensure that there are no known issues or updates that could address this problem.

Example

No code snippet is provided as the issue does not imply a specific code change, but rather a modification to OpenClaw's behavior or configuration.

Notes

The issue seems to be related to OpenClaw's handling of conversation history and DeepSeek's occasional return of reasoning_content even when thinking is disabled. The provided workaround of restarting the gateway suggests that the issue is related to the in-memory session cache.

Recommendation

Apply workaround: Periodically restart the gateway to clear the in-memory session cache, as this has been shown to temporarily resolve the issue, while investigating a more permanent solution to modify OpenClaw's conversation history handling.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

OpenClaw should strip reasoning_content from assistant messages in the conversation history before sending to DeepSeek when thinking is disabled. Alternatively, detect reasoning_content in history and auto-enable thinking mode for consistency.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING