Key takeaways
- A tool call cut off by the output limit returns HTTP 200. On the Claude API the signal is stop_reason: max_tokens with a tool_use block as the last content block; on OpenAI's Responses API it is status: incomplete with reason max_output_tokens.
- Anthropic's documentation says a response with an incomplete tool_use block must be retried with a higher max_tokens to get the full tool use. Repairing the JSON by hand can produce a valid call with missing arguments.
- Current Claude models allow up to 128K output tokens per synchronous request, so a low max_tokens set in a prototype, not the model, is the usual ceiling.
- Not every 'length' stop is a length stop. Hermes Agent issue #26425 traced false truncations to dropped streams being converted into a synthetic finish_reason length; the fix raised truncation retries from 1 to 3 with growing limits.
- Check the stop reason before parsing tool arguments, on every response. A schema validator alone cannot tell a cut-off call from a complete one when the cut lands between fields.
Cut off by the output limit, a tool call does not fail. Anthropic’s stop reasons documentation puts stop_reason in every successful Claude API response and keeps 4xx and 5xx errors apart, so a cut-off call arrives as HTTP 200. The truncation is one field in the body, and a loop that does not read it passes half a JSON object to the parser.
What happens next depends on the parser. Some throw. Some repair the JSON, and then the agent executes a call with arguments that were never finished.
What does a truncated tool call look like?
Like a normal response with one field set differently. The two largest APIs mark it in different places.
| API | HTTP status | Field to check | Value meaning truncated | Max output per request |
|---|---|---|---|---|
| Claude Messages API | 200 | stop_reason | max_tokens | 128,000 tokens |
| Claude Messages API | 200 | stop_reason | model_context_window_exceeded | Bounded by 1M context window |
| OpenAI Responses API | 200 | status, incomplete_details.reason | incomplete, max_output_tokens | Model-specific |
| OpenAI Chat Completions | 200 | finish_reason | length | Model-specific |
The Claude case to watch is max_tokens with a tool_use block as the last content block. Anthropic’s documentation says such a response needs a retry with a higher max_tokens to get the full tool use; the partial block does not carry the complete input.
Why does truncation hit tool calls in particular?
Because tool arguments are often the longest thing the model writes in a turn. A tool that writes a file, sends a document or posts a long message carries its whole payload in the arguments. A max_tokens value that comfortably fits a chat answer can end in the middle of a file body.
The ceiling is rarely the model. Current Claude models allow up to 128,000 output tokens per synchronous request, according to Anthropic’s models overview re-checked on 15 October 2026. The usual ceiling is a value someone set while prototyping. Aggregating finish reasons from your traces is the quickest way to see how many runs that old value is cutting off.
A second cause sits at the other end of the window. If input plus output fills the model’s context window first, Claude stops with model_context_window_exceeded instead. Anthropic says to treat that as truncated too. Raising max_tokens will not help there; the input has to shrink.
Why not repair the JSON and carry on?
Because a repaired call can be valid and wrong.
When the cut lands mid-string, a repair closes the string and the object. The call now parses, passes the schema, and writes half a file. When the cut lands between fields, the result can be a complete object with a required field missing, or an optional one silently absent. This is the same gap as a call whose schema passed and whose values were wrong, produced by the loop rather than the model.
Anthropic’s guidance is direct: retry the request with a higher max_tokens to get the full tool use. OpenAI’s structured outputs guide checks for an incomplete status before parsing and treats it as an error.
Was it really the output limit?
Not always, and a wrong diagnosis sends the retry in the wrong direction.
Hermes Agent issue #26425, opened on 15 May 2026, reported truncation errors across several models and providers. The maintainers traced part of it to streams that dropped mid-response being converted into a synthetic finish_reason of length. A network stall was being reported as an output cap. The fix, in PR #36705, separated network interruptions from real truncation, raised tool-call truncation retries from 1 to 3 with progressively larger output limits, and kept the request’s original cap as a floor so a high default was not lowered to 8K or 12K.
The lesson for any loop: a length stop from a stream that ended early is a network failure. Retry it as one, not by raising the limit.
| Cause | Signal | Retry that helps | Retry that does not |
|---|---|---|---|
| Output limit reached | stop_reason max_tokens, or finish_reason length on a complete stream | Same request, higher max_tokens | Repairing the JSON |
| Context window full | stop_reason model_context_window_exceeded | Smaller input: clear old tool results, compact | Higher max_tokens |
| Stream dropped | No final stream event; client may synthesise a length stop | Same request, same limit, network backoff | Higher max_tokens |
What should the loop check, and in what order?
Our recommended order, which is editorial judgement built on the provider guidance above:
- Read the stop reason before touching content. On Claude,
max_tokensormodel_context_window_exceeded; on OpenAI,incompleteorlength. - If the last block is a tool call, do not execute it. Not partially, not after repair.
- Check the stream ended cleanly. A stream without its final event is a network failure, not a length stop.
- Retry with a higher output limit, a bounded number of times. Hermes Agent settled on 3 attempts; set a ceiling below the model’s 128,000-token maximum that you are willing to pay for.
- If the payload is genuinely large, change the tool. Write in chunks or pass a reference to stored content instead of the content itself.
The question for the loop’s owner: when was max_tokens last changed, and does the code read stop_reason before it parses a single argument?
Frequently asked questions
Why does my agent's tool call have incomplete JSON?
Most often because the response hit the max_tokens limit while the model was writing the tool arguments. The API returns HTTP 200 and marks the stop reason, so the loop must check it before parsing.
What should I do when stop_reason is max_tokens during tool use?
Anthropic's documentation says to retry the request with a higher max_tokens to get the full tool use. Do not execute the partial call.
How do I detect truncation on the OpenAI Responses API?
Check whether response.status is incomplete and incomplete_details.reason is max_output_tokens. OpenAI's structured outputs guide uses that condition before parsing JSON.
What is model_context_window_exceeded?
A Claude stop reason meaning generation stopped because input plus output filled the model's context window, not your max_tokens. Anthropic says to treat it as a truncated response.
Can a network drop look like a max_tokens truncation?
Yes, in some clients. Hermes Agent found that streams dropped mid-response were being converted into a synthetic length stop, which triggered the wrong retry logic.
Method and sources
- Anthropic, Handling stop reasons, Claude API documentation, read 13 and re-checked 15 October 2026. Source of the 7 stop reason values, the guidance on incomplete tool_use blocks at max_tokens, model_context_window_exceeded, and the statements that stop_reason is part of every successful response and that 4xx and 5xx errors are distinct from stop reasons.
- Anthropic, Models overview and Context windows, read 13 and re-checked 15 October 2026. Source of the 128K maximum output per synchronous request, the 1M-token context windows and the overflow behaviour.
- OpenAI, Structured outputs guide, read 13 October 2026. Source of the status incomplete and incomplete_details.reason max_output_tokens check.
- OpenAI, openai-python SDK, src/openai/types/chat/chat_completion.py, read 13 October 2026. Source of the Chat Completions finish_reason value length, documented as the maximum number of tokens specified in the request being reached.
- NousResearch, hermes-agent issue #26425, opened 15 May 2026, fixed in PR #36705. Source of the synthetic finish_reason length from dropped streams and the change from 1 to 3 truncation retries with growing max_tokens.
- The order of checks in the last section and the retry ceiling are our editorial judgement. We ran no truncation experiment of our own.