[BUG] API 400 "messages[1].role must be either 'user' or 'assistant', but got 'system'" (v2.1.156)
Open 💬 19 comments Opened May 29, 2026 by pisahaochi
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?
Bug Description
Claude Code 2.1.156 appears to send an invalid system role inside the messages array when calling the Anthropic Messages API.
This results in the following API error:
API Error: 400 messages[1].role must be either 'user' or 'assistant', but got 'system'
### What Should Happen?
Claude Code should either:
place system prompts in the top-level system field
or ensure messages[] only contains user / assistant roles
The request should be accepted by the Anthropic API.
### Error Messages/Logs
```shell
API Error: 400 messages[1].role must be either 'user' or 'assistant', but got 'system'
Steps to Reproduce
- Start Claude Code normally
- Enter any prompt, for example: test
Claude Model
Other
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
2.1.156
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
Windows Terminal
Additional Information
<img width="1178" height="324" alt="Image" src="https://github.com/user-attachments/assets/c886c2ed-e9d3-4b4a-ba6a-96dd0484fd2d" />
21 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
This is indeed a problem; I've encountered it too.
npm install -g @anthropic-ai/claude-code@2.1.153
use version 153, the problem won't appear
This does not appear to be an exact duplicate.
I can reproduce this issue in normal Claude Code usage with the default setup and even the simplest prompt (
test).No custom agents or Anthropic-compatible providers are involved.
The issue occurs immediately for every prompt and appears to affect standard chat usage.
speed so fast
yes, but this version have thw problem
So whether the change of the format of API intentioned or unintentioned?
indeed, so let's coding at this version while waiting for bug solving for now.
That’s all I can do for now; I’ve installed the stable version for the time being.
claude install stableecho 'ln -snf ~/.local/share/claude/versions/2.1.153 ~/.local/bin/claude 2>/dev/null' >> ~/.zshrc
The API of deepseek may also have issues, possibly due to some updates made to Claude code
!IMG_20260529_111249.jpg
This solution resolved my problem.
Adding context that may help you avoid bouncing between 2.1.153 ↔ 2.1.154 ↔ 2.1.156: this is the same regression family I've been tracking across 50+ open issues since 2026-05-24. Pinning 2.1.152 (one before 2.1.153) is the only version known not to emit the bad shape.
The cluster shape
The bug is that Claude Code emits an "Anthropic-format" request body but places the
systemcontent insidemessages[]instead of using the top-levelsystemfield. The Anthropic API rejects this with a 400. The position of the badsystemrole drifts across versions but the underlying defect is the same:messages[0]carriesrole: "system"after/compact,/clear, or model-switch (see #63147 13F sub-pattern in my synthesis comment)messages[0]carriesrole: "system"more broadly — fresh sessions also hit it (#63366, #63457, the duplicates that brought you here)messages[1]carriesrole: "system"(this issue, plus reports surfacing right now)The shift
messages[0] → messages[1]across 154 → 156 strongly suggests the upstream attempted a partial fix between these versions (perhaps "skip the first message if it's system") rather than treating thesystemfield correctly. Whatever the fix attempt was, it has not resolved the defect — it has only moved the failing index.For third-party Anthropic-compatible providers (DeepSeek, etc.) the failure is the same — they validate against the same Anthropic schema. That's why your DeepSeek attempts also 400.
Workaround that actually holds
The "downgrade to 2.1.153" advice in the thread is unstable because 2.1.153 also hits this, just with a more specific trigger (post-
/compact//clear/ model-switch). If your session never hits those operations, 2.1.153 will appear to work — but it will fail when you next compact or change models.The known-stable version is 2.1.152. You can pin it with:
or, if you use
nvm/ multiple installs, lock the symlink as1394225561suggested above (their approach generalizes to any installed version).If you want a hook that warns you when Claude Code drifts back onto an unstable version (e.g. an autoupdate puts you on 2.1.156), there's an advisory hook for this:
claude-code-version-pin-advisor.shinyurukusa/cc-safe-setup(PR #460, May 29). It checks the running version against a list of known-unstable releases and emits a stderr warning at session start — silent on 2.1.152, vocal on 2.1.153–156. Fail-open, never blocks.What I'd want the maintainers to see
systemrole atmessages[0]symptom you're hitting). Fixing the underlying request-body construction would resolve both clusters in one move.Tracking 50+ open issues against this in my notes — will keep this comment updated if 2.1.157+ resolves it or if the failing index moves again.
2.1.157 已经不报错了
<img width="2731" height="1234" alt="Image" src="https://github.com/user-attachments/assets/8c51fda2-dcaa-42be-ae4b-4e29834a73a3" />
@mozhuanzuojing — thank you for the v2.1.157 confirmation (and for screenshotting it). This is the first independent report I've seen that v2.1.157 resolves the failing-index drift from v2.1.156, so it's a load-bearing data point for everyone in this thread.
Calibrating what "fixed" likely means here
The trigger paths I want to flag for verification, before we can call this comprehensively resolved across the cluster:
400is gone, ✅./compact— was the most reproducible trigger on 2.1.153 (sub-pattern 13F). If/compactstill fires themessages[N].role: systemshape on 2.1.157, the fix is only partial./clear— separate trigger from/compact, hit on 2.1.154+.If you (or anyone) can run one or more of those in v2.1.157 and post the result, that's the cleanest signal on whether the underlying request-body construction bug is fixed, or whether the v2.1.157 patch is another "moved the failing index" partial fix like the one between 154 → 156 turned out to be.
What I'm updating on my side
I'll mark v2.1.157 as provisionally clean in yurukusa/cc-safe-setup's
claude-code-version-pin-advisor.sh(PR #460) once a second independent reproduction of one of the harder triggers (/compactor model-switch) lands. Right now your fresh-session report is the only data point I have; if it holds across the harder triggers, the advisor will go silent on 2.1.157 too.If anyone else in this thread upgrades and confirms, please post the trigger you tested (compact, clear, model-switch, or fresh) so the picture gets pinned faster. Thanks again @mozhuanzuojing for the confirmation — the screenshot with the API call succeeding is exactly the kind of evidence that makes this tractable.
confirming this still exists on 2.1.157, 2.1.158, 2.1.159
Experiencing this with 2.1.161 (VS Code plugin):
<img width="1410" height="995" alt="Image" src="https://github.com/user-attachments/assets/d0976267-0110-45f6-93e6-dc8d956fc927" />
claude install stablenow will install 2.1.153 and it worksconfirming this still exists on 2.1.168
What version has a fix?
Is it fixed?
Now avalilable?
This issue sitll open..