[BUG] Multi-turn HTTP 400 on openrouter-routed DeepSeek V4 Flash; same env works with MiniMax-M3
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Multi-turn HTTP 400 when Claude Code is routed through OpenRouter to DeepSeek V4 Flash. First turn succeeds, every subsequent turn returns "API Error: 400 Provider returned error" and the session is unrecoverable. Same env, same Claude Code version, works fine with MiniMax-M3 (TokenRouter, 220+ multi-turn turns, 0 errors).
What Should Happen?
Multi-turn conversations should complete without errors when Claude Code is routed through OpenRouter to any supported model. The thinking block Claude Code generates on turn N should be preserved or translated on turn N+1 in a way the routed model accepts. Models that require thinking passback (per their own API contract) should not break Claude Code's session on the second turn.
Error Messages/Logs
API Error: 400 Provider returned error
From the session JSONL (turn 1 then turn 2 of the same conversation):
Turn 1 (success):
model: deepseek/deepseek-v4-flash-20260423
provider: DeepSeek
stop_reason: tool_use
input_tokens: 24881
output_tokens: 272
content[0].type: thinking length: 823 signature: <empty>
content[1].type: tool_use name: Skill
Turn 2 (400):
model: <synthetic>
provider: <none>
stop_reason: stop_sequence
isApiErrorMessage: true
apiErrorStatus: 400
error: unknown
input_tokens: 0
output_tokens: 0
content[0].text: "API Error: 400 Provider returned error"
The thinking block on turn 1 has an empty signature field. The next request fails before any tokenization, suggesting the request body fails validation upstream.
Steps to Reproduce
- Install Claude Code: npm install -g @anthropic-ai/claude-code
- Configure ~/.claude/settings.json with:
"env": {
"ANTHROPIC_BASE_URL": "https://openrouter.ai/api",
"ANTHROPIC_AUTH_TOKEN": "<openrouter-key>",
"ANTHROPIC_MODEL": "openrouter/auto"
}
- Launch claude interactively from a terminal.
- Send a normal coding question, e.g. "read README.md and summarize".
- The first assistant turn succeeds (tool use, thinking block, etc.).
- Send any follow-up turn, e.g. "now add a section on installation".
- Response: "API Error: 400 Provider returned error".
- From this point every subsequent turn in the same session also returns 400.
- The session must be closed and a new claude process started to recover.
Pinning ANTHROPIC_MODEL to a specific non-Claude model on OpenRouter (e.g. deepseek/deepseek-v4-flash-20260423) reproduces the same 400. The auth env var can be set to either ANTHROPIC_AUTH_TOKEN or ANTHROPIC_API_KEY; the failure is not auth-related.
Claude Model
openrouter/auto (resolves to deepseek/deepseek-v4-flash-20260423 via OpenRouter NotDiamond routing)
Is this a regression?
It's not a version regression.
Last Working Version
Not a Claude Code version regression — same version 2.1.178 works fine with model=MiniMax-M3 (TokenRouter, three sessions, 370+ multi-turn assistant turns, 0 errors). The 400 reproduces on 2.1.178 AND 2.1.179 when the routed model is DeepSeek V4 Flash. The change that introduced the failure was the model/provider choice, not the Claude Code version.
Claude Code Version
2.1.179 (Claude Code)
Platform
OpenRouter (https://openrouter.ai/api) — Anthropic Skin translation layer
Operating System
Fedora Linux 44 (Workstation Edition), kernel 7.0.8-200.fc44.x86_64
Terminal/Shell
Ghostty (xterm-ghostty), bash 5.3.9, Wayland, GNOME
Additional Information
- The thinking block on turn 1 has an empty/missing signature field in the JSONL. This matches the failure mode described in issue #62963 (2.1.152 thinking-by-default regression) but reproduces on the current 2.1.179 build.
- DeepSeek's API contract (api-docs.deepseek.com/guides/thinking_mode) requires the thinking content to be passed back in the assistant's prior message on subsequent requests. Claude Code's serializer does not preserve it correctly when routing through OpenRouter to DeepSeek, causing 400.
- Related: musistudio/claude-code-router#1378 (DeepSeek V4 Pro thinking-mode + tool calls fails identically on the same env, with a working translation-proxy workaround).
- A translation proxy that injects reasoning_content on the round-trip (e.g. laichunpongben/deepseek-reasoning-proxy) is the only working workaround I have found. Pinning to a non-thinking-passback model also works.
- I tested with only ANTHROPIC_AUTH_TOKEN set (no ANTHROPIC_API_KEY) and with both set — the 400 reproduces either way. The auth conflict warning in the boot banner is a separate issue and is not the cause of the 400.
- Cost: I have not been charged for the failing requests. The 400 is rejected at the provider edge before any model inference.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗