claude-code - 💡(How to fix) Fix 400 role 'system' is not supported — client builds malformed request after large, twice-compacted session (unrecoverable in-place)

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…

After a long-running session that twice exceeded ~1M input tokens and was compacted twice, every subsequent turn fails with:

API Error: 400 role 'system' is not supported on this model

The failure is deterministic — identical on every retry. The persisted session transcript (JSONL) contains no role:"system" message anywhere; the malformed system-role entry is introduced at request-construction time, not present in stored history.

The session is therefore permanently unusable in-place: /compact cannot recover it, because compaction also issues an API call built the same way.

Error Message

API Error: 400 role 'system' is not supported on this model

Root Cause

The session is therefore permanently unusable in-place: /compact cannot recover it, because compaction also issues an API call built the same way.

Code Example

API Error: 400 role 'system' is not supported on this model
RAW_BUFFERClick to expand / collapse

Environment

  • Claude Code: 2.1.139
  • Platform: Linux 6.8.0, CLI entrypoint
  • Model: claude-opus-4-7, 1M context (endpoint /v1/messages?beta=true)

Summary

After a long-running session that twice exceeded ~1M input tokens and was compacted twice, every subsequent turn fails with:

API Error: 400 role 'system' is not supported on this model

The failure is deterministic — identical on every retry. The persisted session transcript (JSONL) contains no role:"system" message anywhere; the malformed system-role entry is introduced at request-construction time, not present in stored history.

The session is therefore permanently unusable in-place: /compact cannot recover it, because compaction also issues an API call built the same way.

Evidence (from the session transcript)

  • 5,355 transcript events; valid JSONL, 0 parse errors.
  • Two compact_boundary events:
    • manual trigger — preTokens: 1001871postTokens: 11727
    • auto trigger — preTokens: 974919postTokens: 11880
  • An earlier, separate 400 invalid_request "Prompt is too long" preceded the first (manual) compaction.
  • The last successful turn completed normally on claude-opus-4-7. The very next user message — plain text, no attachments — produced the 400 role 'system' error.
  • 5 consecutive attempts (1 original + 4 retries) all failed identically.
  • Grep of the full transcript for "role":"system" / "role": "system": 0 hits.
  • Each failed attempt appends a synthetic assistant error message (model: "<synthetic>", isApiErrorMessage: true) to history.

Expected behavior

The client should never place a system-role message in the messages array — system content belongs in the top-level system request parameter. Outgoing messages should be validated to role ∈ {user, assistant} before send.

Impact

A session in this state is unrecoverable in-place. /compact fails for the same reason. The only escape is /clear (total context loss) or abandoning the session — a hard data-loss cliff for long, heavily-compacted sessions.

Suspected area

The injected system-role message is generated at request-build time, likely in the context-management / post-compaction summary reconstruction path (this session had been compacted twice from ~1M tokens). Worth checking how the post-compaction summary is mapped into the messages array.


The full session transcript (~17 MB, contains internal project context) is available privately on request.

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

The client should never place a system-role message in the messages array — system content belongs in the top-level system request parameter. Outgoing messages should be validated to role ∈ {user, assistant} before send.

Still need to ship something?

×6

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

Back to top recommendations

TRENDING