Your app shows reports that end mid-sentence, and the response has stop_reason max_tokens. What happened?
Why D is the answer
The reply reached the max_tokens limit you set
max_tokens means generation hit your limit, so the reply is incomplete. Check for it rather than assuming every 200 response is a finished answer.
In detail
- stop_reason max_tokens means generation hit your limit, so the reply is incomplete.
- Check it on every response rather than assuming a 200 is a finished answer.
- Treat a max_tokens stop as an incomplete answer in your interface.
Use case
An illustrative scenario, not a real incident.
A report tool sets max_tokens to 500, and long reports stop mid-sentence with status 200. Checking stop_reason, the app raises the limit or asks the model to continue.
See it in different ways
flowchart LR
A{"stop_reason"} -->|"end_turn"| B["Use the answer"]
A -->|"tool_use"| C["Run tools, send results"]
A -->|"max_tokens"| D["Reply was cut off"]
A -->|"pause_turn"| E["Send content back to continue"]
A -->|"refusal"| F["Handle the refusal"]stateDiagram-v2 [*] --> Response Response --> Complete: end_turn Response --> RunTool: tool_use Response --> CutOff: max_tokens Response --> Blocked: refusal Response --> Continue: pause_turn Continue --> Response: send content back
flowchart TD
Q{"What is stop_reason?"}
Q -->|"end_turn"| A0["Complete reply"]
Q -->|"max_tokens"| A1["Cut off by your limit"]
Q -->|"stop_sequence"| A2["A stop sequence fired"]Key point: A 200 can still be a cut-off reply.
Why the other options are wrong
- A. The model chose to stop early
- A normal finish reports end_turn.
- B. A safety filter removed the ending of the reply after it finished generating
- A refusal reports stop_reason refusal.
- C. A stop sequence fired in the text
- A stop sequence reports stop_sequence.

