Provider API: /v1/messages rejects mid-conversation role:"system" messages (400 Invalid input at messages.N.role)
Dieses Issue hat noch niemand übernommen.
Bewertung
- Schwierigkeit
- 3/5
- Geschätzter Aufwand
- 1-2 Tage
- Anfängerfreundlichkeit
- 52/100
- Issue-Typ
- Bug
- Klarheit
- Größtenteils klar
- Aktivitätsstatus
- Aktiv
- Tech-Stack
- bash
- Bereich
- api, backend-api-design
Rechercherichtung
Start at the POST /provider/v1/messages request validation and reproduce the supplied curl cases, comparing a mid-conversation system role with the accepted top-level system forms. Done means compliant system entries return a normal completion, or intentionally unsupported input produces a distinct documented error instead of the generic role validation failure.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
Summary
POST https://api.commandcode.ai/provider/v1/messages rejects any request whose messages array
contains a {"role":"system"} entry, with HTTP 400
{"type":"error","error":{"type":"invalid_request_error","message":"Invalid input at messages.1.role"}}.
Mid-conversation system messages are a documented, generally-available Anthropic Messages API
capability, and the current Claude Code build emits them routinely — so Claude Code cannot complete
a single turn against this endpoint, on any model.
The same endpoint accepts a top-level system field (both string and content-block array), and
accepts user / assistant roles inside messages. The trigger is specifically the system role
appearing inside messages.
Expected Behavior
Per Anthropic's specification
(https://platform.claude.com/docs/en/build-with-claude/mid-conversation-system-messages):
- mid-conversation system messages are available on the Claude API, Amazon Bedrock and Google Cloud;
- they are supported on Claude Opus 5.5 (among others);
- "No beta header is required for mid-conversation system messages";
- placement rules: the entry must not be first in
messages, must immediately follow auserturn,
and must precede anassistantturn or end the array.
/provider/v1/messages should accept that shape, or — if it is intentionally unsupported — return a
specific documented error rather than the generic Invalid input at messages.N.role, so clients can
detect it and rewrite the request (e.g. by hoisting the content into the top-level system field).
Actual Behavior
400 {"type":"error","error":{"type":"invalid_request_error","message":"Invalid input at messages.1.role"}}
Steps to reproduce the issue
- Minimal repro plus two controls, all against the same key / model (2-message body, so the
systementry sits at index 1 and is both last-in-array and directly after theuserturn —
i.e. fully compliant with the documented placement rules):
KEY="$CMDCODE_KEY"
BASE=https://api.commandcode.ai/provider/v1/messages
H=(-H "Authorization: Bearer $KEY" -H 'content-type: application/json')
# (a) mid-conversation system role -> 400
curl -sS "${H[@]}" -X POST "$BASE" -d '{"model":"claude-opus-5-5","max_tokens":16,
"messages":[{"role":"user","content":"hi"},{"role":"system","content":"ctx"}]}'
# -> 400 {"type":"error","error":{"type":"invalid_request_error","message":"Invalid input at messages.1.role"}}
# (b) the SAME text as a top-level system array -> 200
curl -sS "${H[@]}" -X POST "$BASE" -d '{"model":"claude-opus-5-5","max_tokens":16,
"system":[{"type":"text","text":"ctx"}],"messages":[{"role":"user","content":"hi"}]}'
# -> 200
# (c) top-level system as a plain string -> 200
curl -sS "${H[@]}" -X POST "$BASE" -d '{"model":"claude-opus-5-5","max_tokens":16,
"system":"ctx","messages":[{"role":"user","content":"hi"}]}'
# -> 200
- The rejection is about the
rolevalue itself, not about thecontentshape or any field on the
entry: it reproduces with"content":"ctx"(string), with content-block arrays, and at any index. - For reference, this is the request the current Claude Code build actually sends (captured
verbatim; notemessages[1]):
{"model":"claude-opus-5","max_tokens":32000,
"system":[{"type":"text","text":"You are Claude Code, Anthropic's official CLI for Claude."}],
"messages":[{"role":"user","content":[{"type":"text","text":"hi"}]},
{"role":"system","content":[{"type":"text","text":"<context injected mid-session>"}]}]}
(Reproduced identically on 2.1.274 and 2.1.278; the request shape is emitted by the CLI, not
version-specific.)
- Isolation — same key, same model (
claude-opus-5-5), one variable changed per row. Only the
systemrole insidemessagesfails; every other shape returns 200. Note that the added
anthropic-betaheader makes no difference, consistent with the feature requiring no beta header.
messages contents |
result |
|---|---|
user only |
200 |
user + assistant + user |
200 |
user + system (index 1, last in array) |
400 |
system as top-level string |
200 |
system as top-level content-block array |
200 |
user + assistant, each with content-block arrays |
200 |
user + system, with anthropic-beta: context-1m-2025-08-07 added |
400 (identical message) |
user + system, with no anthropic-beta header |
400 (identical message) |
Command Code Version
N/A — reporting against the Provider API directly
Operating System
Linux
Terminal/IDE
server-side / n/a
Shell
bash
Session file (optional)
No response
Fix prompt (optional)
POST /provider/v1/messages rejects any request whose messages array contains a {"role":"system"}
entry, returning 400 {"error":{"type":"invalid_request_error","message":"Invalid input at messages.N.role"}}.
Mid-conversation system messages are a documented Anthropic Messages API feature (no beta header
required, supported on Opus 5.5) and Claude Code sends them on every turn, so the endpoint is
currently unusable for that client.
Reproduce: POST a body with messages:[{"role":"user",...},{"role":"system",...}] -> 400. The same
content as a top-level system field (string or block array) -> 200, and user/assistant roles in
messages -> 200, so the trigger is specifically the system role inside messages.
Check: the request above returns a normal completion, and a mid-conversation system entry placed
per Anthropic's rules (not first, immediately after a user turn, last in the array or before an
assistant turn) is accepted. If the shape is intentionally unsupported, return a distinct error code
instead of the generic Invalid input, and document the limitation on the Provider API errors page.
Additional context
- Environment: Ubuntu 24.04 (kernel 6.8.0-139), x86_64. Client: Claude Code 2.1.274, driven headless.
Provider:base_url = https://api.commandcode.ai/provider/v1, API-key auth. - All Claude models reproduce identically; the failure is not model-specific. A minimal, model-only
control (POST /provider/v1/messageswith the same model and a plain user message) returns 200, so
credentials and routing are fine. - Impact: Claude Code cannot complete any turn. The identical limitation forced a client-side choice
between dropping mid-session context injection or not using this gateway. - Related: this is the same class as #850 (Anthropic-spec shape rejected on
/v1/messages) and the
/responsesinput-item family in #893. Both show that aligning the request validation with the
documented Anthropic / Responses shapes is the accepted direction. - Minor, general request: the error names
messages.1.role(good) butparam:"input"style errors on
/responsesname no index or item type. Naming the offending index and type consistently would
make this class of bug self-diagnosing.
- Vorherrschende Sprache
- Keine Sprachdaten
- Sterne
- 4k
- Forks
- 357
- PR-Merge-Kennzahlen
- Keine gemergten PRs in 30 T.
Entwicklungsumgebung
Dieses Projekt bietet weder Dev-Container noch Dockerfile noch Beitragsleitfaden – die Einrichtung liegt bei Ihnen. Beginnen Sie mit der README; die allgemeinen Schritte stehen in unserem Leitfaden für den ersten Beitrag.
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus CommandCodeAI/command-code
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 68/100
CommandCodeAI/command-code#933 ·
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 68/100
CommandCodeAI/command-code#855 ·
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 78/100
CommandCodeAI/command-code#841 · 1 Kommentar ·
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 68/100
CommandCodeAI/command-code#655 · 1 Kommentar ·
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 68/100
CommandCodeAI/command-code#608 ·
Alle Issues in CommandCodeAI/command-code
Ähnliche Issues
-
priority: low 🌱 type: enhancement 💅🏼
Schwierigkeit 2/5 Ein halber Tag Anfängerfreundlichkeit 84/100
nebari-dev/llm-serving-pack#199 ·
Maintainer antworten meist innerhalb von 3 Tagen
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 76/100
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 78/100
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 84/100
linebender/parley#849 ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 76/100
rohitg00/agentmemory#1428 ·
Maintainer antworten meist innerhalb von 1 Tag