TL;DR — context_length_exceeded (HTTP 400) fires when input tokens + requested max_tokens exceed the model's context window. It is deterministic: the same oversized request fails every time, so retries are pointless. Fixes, in order of preference for coding work: trim or summarize conversation history, lower max_tokens, stop pasting whole files when a diff would do, or move the session to a model with a bigger window. Agents hit it mid-session because tool-call loops grow history on every step until the ceiling arrives.
The error
HTTP 400
{
"error": {
"message": "This model's maximum context length is 128000 tokens. However, your messages resulted in 131447 tokens. Please reduce the length of the messages.",
"type": "invalid_request_error",
"code": "context_length_exceeded"
}
}
The numbers vary by model and request; the shape doesn't. Variants of the message also count max_tokens explicitly ("...your messages resulted in X tokens and max_tokens was set to Y").
The math that actually applies
The constraint is:
prompt_tokens + max_tokens (requested completion budget) ≤ model context window
Two non-obvious consequences:
- A request can fail before generating anything. If your history is 120k tokens and you ask for
max_tokens: 16000on a 128k model, the request is rejected up front even though the reply might have been short. - "It worked yesterday" means nothing. Context windows are per-request; yesterday's session was shorter. The same code with a longer history fails.
Why coding agents hit this mid-session
Tool-calling agents (Claude Code, Codex CLI, aider, custom LangChain loops) replay the full conversation on every step: every file read, every diff, every tool result gets appended. Context grows monotonically until either the agent compacts it or the window overflows. The failure therefore shows up at the worst time — deep into a productive session, not at the start.
Fixes, ranked
1. Trim history before the window fills. Drop or summarize old tool results — a file you read 40 steps ago and already edited rarely needs to stay verbatim. Most agent frameworks expose a compaction/summarization hook; use it proactively at ~80% of the window rather than reactively at 100%.
2. Lower max_tokens. If you set a large completion budget "just in case," you are reserving window you rarely use. Size it to the longest reply you actually need.
3. Send less per message. Paste the failing function, not the whole file; send diffs, not before/after copies. In agent settings, prefer targeted file-range reads over whole-file reads.
4. Chunk the task. Long document processing belongs in a map-reduce shape: process pieces, then merge summaries — not one giant prompt.
5. Switch to a larger-window model. Sometimes the task legitimately needs more context. Windows differ substantially across current models and providers — check the current figures rather than folklore, since they change between releases. If your tooling routes by task, a long-context model can be selected only for the steps that need it, which is cheaper than running everything on the biggest window available — how phase-aware routing does this.
What not to do
- Don't retry. Same input → same overflow. Retry loops on a 400 just burn time (and, on some stacks, money for prompt processing that never completes).
- Don't blindly truncate the middle of the history. Cutting arbitrary messages can orphan tool calls from their results, which several providers reject as malformed history — you trade one 400 for another.
Prevention
- Log
prompt_tokensfrom each response'susageblock and alert at a threshold; overflow is visible many steps before it happens. - Set your agent's auto-compact threshold below the model's window with margin for the completion budget.
- For mixed workloads, route long-context steps to long-window models and everything else to cheaper ones instead of paying long-context prices everywhere.
Part of the LLM API Error Reference — errors indexed by their exact strings.