Jev max_tokens_exceeded: State Too Long
Last checked · Independent guide, not affiliated with TypeSafe AI
Jev returns HTTP 400 with the body {"detail":{"error_type":"max_tokens_exceeded"}}, and no message, when a request is over its token budget. In our tests, 32,204 input tokens went through and about 33,600 were rejected, matching TypeSafe's documented 32k limit for the state plus the longest question. Trim or split the state.
The exact error
Section titled “The exact error”{ "detail": { "error_type": "max_tokens_exceeded" } }There is no message field, which makes this one easy to miss in logs that only print message. The Python SDK raises it as TypeSafeBadRequestError with the raw body in the text: 400 {"detail":{"error_type":"max_tokens_exceeded"}}.
Where the limit is
Section titled “Where the limit is”TypeSafe documents two budgets:
- 64k tokens per request, covering the state and all questions together.
- 32k tokens for the state plus the single longest question.
The 32k rule is the one you will hit first. We sent a single short question with log files of increasing size on September 19, 2026:
| Input tokens reported | Result |
|---|---|
| 26,867 | 200, answered in 1.3 s |
| 30,873 | 200 |
| 32,204 | 200 |
| about 33,600 | 400 max_tokens_exceeded |
| about 54,000 | 400 max_tokens_exceeded |
The cutoff sits right around 32k tokens, even though the request was far below 64k. TypeSafe’s docs translate the budget into roughly 150,000 characters of English. Dense text with numbers and IDs tokenizes worse: our log lines averaged about three characters per token, so roughly 105,000 characters of log text was already too much.
OpenRouter and Cloudflare list a 32,000-token context window for Jev, so the practical limit is similar on every channel.
How to fix it
Section titled “How to fix it”1. Send only what the question needs. This is also TypeSafe’s accuracy advice: Jev 1.13 gets less accurate as the state fills with unrelated material. Filter records, drop boilerplate and send the relevant fields rather than whole documents.
2. Split long inputs and combine in code. For a long document, ask the same question per section and combine the answers: for example, flag the document if any section’s noul is above your threshold, or take the maximum score.
3. Filter first with a cheap question. Ask a Noul per chunk (“Is this passage relevant to X?”) and send only the relevant chunks to the real question. TypeSafe’s RAG-passage cookbook uses this pattern.
4. Check the size before sending. Estimate tokens from characters (about four per token for prose, fewer for data), and keep a margin. After a successful call, usage.input_tokens gives the real count.
Many questions and the budget
Section titled “Many questions and the budget”Questions count toward the 64k request budget, but in the 32k rule only the longest question counts. In practice, adding more questions is cheap: 20 short yes/no questions added about 256 tokens in our test. Long Choice option descriptions add more, so keep them concise when the state is already large.
Should you retry?
Section titled “Should you retry?”No. The same request will fail the same way, and the SDKs do not retry 400 errors. Shrink the request.
Related: Jev API errors, State, Jev limitations.