Repository navigation
Provider API: generic 400 invalid_request_error (trace_id only) for long tool-heavy requests, far below the advertised 1M context #976
Description
Summary
The Provider API returns a generic 400 invalid_request_error (body carries only a trace_id, no code/param) for a long, tool-heavy OpenAI-compatible request on deepseek/deepseek-v4.1-flash, even though /provider/v1/models advertises context_length: 1000000 and the request is well under that. Once a session reaches this state, every subsequent request with the same history is rejected; a fresh session on the same key/model works.
Environment
- Endpoint:
POST https://api.commandcode.ai/provider/v1/chat/completions - Model:
deepseek/deepseek-v4.1-flash(also seen on the same class of requests withdeepseek/deepseek-v4-flash) - Client: OpenCode v2 +
opencode-cmd-provider(OpenAI Chat Completions,stream: true,max_tokens: 64000,stream_options.include_usage: true,reasoning_effortset) - Date observed: 2026-10-02
Actual behavior
Command Code API error 400:
{"message":"invalid request error trace_id: <hex>","type":"invalid_request_error"}
The envelope has no code, no param, and no detail — only the trace_id. The same request shape is served with 200 at a slightly smaller size.
Evidence
Raw replays against /provider/v1/chat/completions, same model, same key:
| Request (tool-heavy history from the failing session) | prompt_tokens | Result |
|---|---|---|
| history as-is | 248,690 | 200 |
| + benign system block | 276,250 | 200 |
| + benign system block | 278,091 / 279,491 | 200 |
| + benign system block | ~281,600 | 400 |
| + benign system block | ~286,000 | 400 |
| + benign system block | ~288,000 | 400 |
| + benign system block | ~294,000 | 400 |
- The added block is plain English (
"You are a helpful coding agent. "repeated) — meaningless on its own, so this is not the added content being rejected; identical content passes below the boundary. - Near the boundary (~278k–281k) the same byte-identical body flips between 200 and 400 across consecutive calls (observed repeatedly), which points at inconsistent per-upstream limits behind the gateway rather than a deterministic schema rejection.
- A plain single-user-message request at 290,033 tokens returns 200, so the effective ceiling is not a simple global token cap — it depends on the request's shape/composition.
Representative trace_ids (happy to provide more / the exact bodies):
d3ecfed848e2f9238dcf7df9976151a1 523969ce0769307c4b53a71cd97ba656
c8e65493eb3fc2ee14e67193447bf656 f45d648d521d91dae2fcb830bb1153d7
8cb9128b60428f59c5b57e69fb0baa8d 652bcca23eb260b5461ad1f6dfc70ca9
ff8a514d7208bd743b11e17fb05390f1 ba4cd8f9dbcb28c327e6218ccc1b6243
e3d8bc71d74eaa9a8f882130c5d6f17a 01c842f26a29e9265244ad35ed4df539
a980384c83edd0e23b70f28ae08978a2 07603ff4e5721b6bd2607edb84ff4378
5794a8bf53e87083bd6a5fd908d0bdd8 1db8813539d7ac76d68193b896e5b2c7
2f6228764d00865cf6abce943439e7e9 26bd02da3c32500d8e829ee648a8b24c
Expected behavior
Either serve the request (it is far below the advertised 1M window), or return a diagnosable error — e.g. 413 / context_length_exceeded naming the actual limit and the current input size — instead of a generic 400 invalid_request_error with only a trace_id. The advertised context_length and the effectively served limit should agree.
Impact
- A single long tool-heavy session becomes permanently unusable — every request replays the same history and gets the same 400; retries (the client retries 2–4×) all fail identically.
- The only recovery is starting a new session and losing all context.
- Because the error is generic, it is impossible to distinguish "your prompt exceeded a limit" from "your request body is malformed", and the client cannot auto-compact intelligently.
Notes
- I saw your Reddit reply on the "Deepseek V4 Pro Context Length Capped?" thread asking for
/tracedetails — thesetrace_ids are from the OpenAI-compatible Provider API (not the CLI), so hopefully they are queryable server-side. - I'm happy to share the exact request body (≈1 MB) privately if it helps, or to build a client-side repro with you.
Thanks!
Reproduction files
Two request bodies (secret gist): https://gist.github.com/depler/5c153c6a9e4adac2e63a9d538f0f78b2
control_200.json— the session's outbound body (134 messages) → HTTP 200,prompt_tokens=248690failing_400.json— the same body plus one benignsystemmessage prepended → HTTP 400
(trace_id: 65a715e992e7b714bfc7eae1f34e978a)README.md— the exactcurlcommands and observed results
The only difference between the two files is the extra system message at
messages[0]; the flip to 400 is caused by the resulting request size/shape,
not by the added text.
Activity
depler commentedon Oct 2, 2026
Added the two request bodies as files (secret gist): https://gist.github.com/depler/5c153c6a9e4adac2e63a9d538f0f78b2
control_200.json→ HTTP 200 (prompt_tokens=248690)failing_400.json→ HTTP 400 (trace_id: 65a715e992e7b714bfc7eae1f34e978a) — byte-identical to the control except for ONE extra benignsystemmessage atmessages[0]README.md→ curl commands + observed resultsSo two copy-pasteable examples: same conversation, one returns 200, the other 400.