prompt is too long / context_length_exceeded — what filled the window usually isn't what you just sent
- The limit applies to the whole conversation, not your last message — every request resends everything before it, so a one-liner is often what tips it over.
- Try
/compactfirst, then/clear; longer term, use.claudeignoreto keep directories out of context entirely. - A failed request doesn't shrink the history, which is why one overflow is followed immediately by another. Waiting doesn't help.
The limit applies to the whole conversation, not to your last message. Every request re-sends everything that came before it — earlier turns, every file that was read, every tool result. So the message that finally overflows is often a one-liner. And three different limits produce nearly identical error text; only one of them is fixed by sending less input.
What you're seeing
API Error: 400 {"type":"error","error":{"type":"invalid_request_error","message":"prompt is too long: <your-count> tokens > <limit> maximum"}}
{"error":{"message":"This model's maximum context length is <limit> tokens. However, your messages resulted in <your-count> tokens. Please reduce the length of the messages.","type":"invalid_request_error","param":"messages","code":"context_length_exceeded"}}
{"type":"error","error":{"type":"invalid_request_error","message":"input length and `max_tokens` exceed context limit: <input> + <max_tokens> > <limit>, decrease input length or `max_tokens` and try again"}}
{"type":"error","error":{"type":"invalid_request_error","message":"max_tokens: <your-value> > <limit>, which is the maximum allowed number of output tokens for <model-id>"}}
Numbers are shown as <...> here because they differ per model and per endpoint — the ones in your message are the only ones worth reading.
input length exceeds context limit, and some drop the JSON envelope and print only prompt is too long. Same limit, different packaging — search for both spellings.
The first two are the same problem. The third is that problem plus your output reservation. The fourth is a different limit wearing similar words, and shrinking your input will not move it.
Three limits that get called "context length"
| What it caps | Error text that names it | What actually fixes it | |
|---|---|---|---|
| Input / context window | Everything you send in one request: system prompt, tool definitions, every prior turn, every tool result, every attached file | prompt is too long · maximum context length · context_length_exceeded | Remove content from the conversation |
Output cap (max_tokens) | How much the model is allowed to write back | max_tokens: <n> > <limit> | Lower max_tokens. Your input is irrelevant |
| Input + output together | Input and your requested max_tokens must fit in the window at the same time | input length and max_tokens exceed context limit | Either side works — lower max_tokens or shrink the input |
The third row is the one that surprises people: a request can be rejected before a single output token is generated, because the space you reserved for the answer no longer fits next to the question. Nothing was actually too long. The reservation was too greedy.
Why it fires when you "only sent one line"
There is no per-message limit. Each request carries the entire conversation again, so message N costs the sum of everything from 1 to N. The last message isn't the cause; it's the straw.
What is actually occupying the window, roughly in order of how much people underestimate it:
- Tool results. One directory listing of a repo that still has
node_modules, one read of a lock file, one un-narrowed search across the tree. In the transcript these look like a single short line of output. In the request they are not. - Files read earlier and never released. A file read in step 2 is still being re-sent in step 40.
- Project instruction files loaded automatically at session start. You never see them scroll past, and they are in every request.
- The conversation itself — the part everyone blames first, and usually the smallest.
Two consequences worth internalising:
- A failed request does not shrink the history. That's why one overflow is immediately followed by another: retrying sends the same oversized payload. You have to remove something before retrying.
- The window fills fastest during a successful long task, not during a hard one. Lots of small tool calls that all worked is the classic profile.
Check in this order
1 · Read the two numbers before touching anything#
Every one of the messages above contains your size and the limit. Their ratio decides the strategy:
- Slightly over → compress the conversation (step 3).
- Several times over → something large got pulled in that shouldn't be there (step 5).
- Your input alone is comfortably under the limit but the message names
max_tokens→ go straight to step 6.
Guessing before reading the ratio is what turns this into an afternoon.
2 · Find out how much you are actually using#
Ask the client first — it knows what it has been sending:
/context
For an exact count outside the client, ask the endpoint to count a request without running it:
# <model-id>: copy an id from https://api.9coding.com/v1/models
curl -sS https://api.9coding.com/v1/messages/count_tokens \
-H "Authorization: Bearer sk-9c-xxxxxxxx" \
-H "content-type: application/json" \
-H "anthropic-version: 2023-06-01" \
-d '{"model":"<model-id>","messages":[{"role":"user","content":"paste the text you are about to send"}]}'
Not every compatible endpoint implements this route. If it 404s, fall back to an order-of-magnitude check:
wc -c < the-file-you-are-about-to-paste.txt
As a rough scale: English prose runs a few characters per token, source code fewer, CJK text can approach one token per character. Use this only to decide whether something is obviously too big — never to decide whether something will just fit.
3 · Compress before you clear#
/compact
This replaces the transcript with a summary and keeps working. Do it before you're forced to, not after — compacting has to send the history one more time to summarise it, and a conversation that is already over the limit may not be able to.
4 · Clear when compressing isn't enough#
/clear
/compact keeps a summary; /clear keeps nothing. The distinction matters: if the thing that blew up the window was one enormous tool result, a summary of it is still a summary of it, and may carry a large share of the bulk forward. When the same overflow returns right after compacting, clear instead and restate the task in three sentences.
5 · Stop the repository from loading itself into the window#
Find what is big before you decide what to exclude:
du -sh -- */ 2>/dev/null | sort -h | tail -15
find . -type f -not -path './.git/*' | wc -l
Then keep the usual suspects out of the context entirely:
node_modules/
dist/
build/
.next/
vendor/
coverage/
logs/
*.min.js
*.map
package-lock.json
pnpm-lock.yaml
*.png
*.jpg
*.pdf
*.csv
.claudeignore for Claude Code. Confirm the filename and the scope that the client version you're actually running honours before relying on it.
Lock files and minified bundles deserve special mention: they are single files, they look harmless in a listing, and they are frequently the largest text in the repository.
Also change how you look at files: prefer a targeted search with a few lines of context over reading whole files, and read a range rather than an entire module. Every avoided full read is window you keep.
6 · If the message names max_tokens, lower that — not your input#
# <model-id>: copy an id from https://api.9coding.com/v1/models
# max_tokens below is an arbitrary probe value, not a documented limit
curl -sS -w '\n%{http_code}\n' https://api.9coding.com/v1/messages \
-H "Authorization: Bearer sk-9c-xxxxxxxx" \
-H "content-type: application/json" \
-H "anthropic-version: 2023-06-01" \
-d '{"model":"<model-id>","max_tokens":1024,"messages":[{"role":"user","content":"hi"}]}'
If a minimal request like this succeeds while your real one fails, the input is the problem. If this one fails too, max_tokens is set above what that model allows and no amount of trimming will help.
7 · If it still doesn't fit, the task is too big#
Splitting is not a workaround, it's the fix. One task per session, with the output of each written to a file instead of carried in the conversation, keeps every request small and — the underrated part — reproducible. A four-hour session that ended in an overflow cannot be re-run. Four short ones can.
When it isn't your problem
- The same prompt fits on one endpoint and not another. A gateway may cap the window below what the model itself supports. Compare against the model's documented limit; if they disagree, that's an endpoint policy, not your payload.
- It fails at exactly the same size no matter what you remove. Fixed overhead — system prompt, tool schemas — is taking a share you can't edit from inside the conversation. Reduce the number of enabled tools.
- The failure appeared today with no change to your setup. Available window and default
max_tokensare configuration on the endpoint's side and can move. - Compaction itself fails. That's the one case where you genuinely can't recover in place; start a new session.
An endpoint that doesn't publish its effective context limit is an endpoint where you cannot plan a long task — you can only discover the ceiling by hitting it. Check the operator's status page before you spend the afternoon rewriting prompts; ours is at status.
When reporting it, include the request id — 9Coding error responses carry one in the form (request id: 2026...). That id plus the timestamp, the model name and the full error text lets the exact call be traced. A report that only says it doesn't work cannot be investigated.
Not the same problem
A 429 means the request was the right size and you sent too many of them — see 429 Too Many Requests. A 400 with invalid_request_error but no size in the message is a malformed request, not a large one — see 400 Bad Request in multi-turn conversations. Both are elsewhere.
Related
- 429 Too Many Requests — back off, or raise the limit
- 400 Bad Request in multi-turn conversations — malformed requests that aren't about size
- Model not found — one message, three unrelated causes
- All Claude Code errors — the quick reference table