Truncation Point Finder
Check an output for the structural signs of a cut — unbalanced JSON, an open code fence, a half-written character — against the finish_reason you were given.
These are structural signals from the text alone. Only finish_reason knows the cause — paste it above.
- okEnds without terminal punctuationThe last character is not something a finished sentence ends on.
- okUnclosed brackets or bracesAll brackets balanced.
- okUnterminated string literalA double quote was opened and never closed.
- okStray closing bracket0 closing bracket(s) with no opener — usually a sign the start was cut, not the end.
- okUnclosed code fence0 fence marker(s) — an odd number means a block is still open.
- okEnds mid-characterThe final UTF-16 unit is a lone high surrogate: an emoji or CJK character was cut in half.
- flagEnds on an incomplete list itemA list marker with nothing after it.
- okEnds on an incomplete tagAn angle bracket was opened after the last one closed.
- okEstimated size is at the cap≈ 104 estimated tokens against a cap of 1,024.
- Characters
- 317
- Estimated tokens
- ≈ 104
- Share of your max_tokens
- 10.2%
Why a clean-looking answer can still be truncated
Structural evidence is one-directional. Unbalanced braces mean something went wrong; balanced braces mean nothing at all, because a model that runs out of budget mid-paragraph frequently ends on a full stop. The checks here are worth running because they catch the expensive cases — the JSON your parser will reject, the code block your renderer will swallow the rest of the page into, the emoji cut in half that turns into a replacement character in your database — and because they tell you which one to fix first.
The combination worth knowing is finish_reason: stop with structural damage. That almost always means a stop sequence fired inside legitimate content: the model produced a newline-newline, or the string you set as a delimiter appeared in the answer, and the API cut there and reported a clean stop. It looks identical to a model that decided to end, and it is the one truncation cause people spend a day not finding.
The other common cause is not truncation at all. A response that stops early with a token count nowhere near the cap is usually a model declining, a tool call being emitted instead of content, or a stream that was aborted client-side while the server kept generating and kept billing. Check the cap first because it is cheap; check the transport second, because an aborted stream leaves no trace in the text at all.