unslothai/unsloth · error · GenerationLengthError
The model reached the Max Tokens limit before producing a fi
Error message
The model reached the Max Tokens limit before producing a final answer. Increase Max Tokens or disable thinking, then retry.
What it means
GenerationLengthError is thrown when the stream terminated with finish_reason === "length" (Max Tokens hit) and the model emitted reasoning content but never produced any assistant-facing text — i.e. the entire token budget was consumed by thinking. The message tells the user to raise Max Tokens or disable thinking. It is a typed error class (chat-api.ts:82) so the UI can offer a targeted retry action.
Source
Thrown at studio/frontend/src/features/chat/api/chat-api.ts:1336
}
const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = "";
let completed = false;
// EOF without `[DONE]` or a finish_reason chunk means the stream was cut mid-generation.
let sawTerminalSignal = false;
let terminalFinishReason: string | null = null;
let sawAssistantContent = false;
let sawReasoningContent = false;
const throwIfReasoningOnlyLength = () => {
if (
terminalFinishReason === "length" &&
sawReasoningContent &&
!sawAssistantContent
) {
throw new GenerationLengthError();
}
};
try {
while (true) {
const { done, value } = await reader.read();
if (done) {
completed = true;
if (!sawTerminalSignal) {
throw new StreamInterruptedError();
}
throwIfReasoningOnlyLength();
break;
}
buffer += decoder.decode(value, { stream: true });
let separatorIndex = buffer.search(/\r?\n\r?\n/);View on GitHub (pinned to 203007d190)
Solutions
- Increase the Max Tokens setting for the request/model.
- Disable thinking/reasoning mode for this generation.
- If both are fixed by policy, surface the typed error and let the user retry with adjusted settings rather than retrying blindly.
Example fix
// before payload.max_tokens = 1024; // reasoning eats it all // after payload.max_tokens = 8192; // or: payload.reasoning_effort = 'none';
Defensive patterns
Strategy: validation
Validate before calling
// Before sending: budget for reasoning overhead
const isReasoning = modelSupportsThinking(payload.model);
if (isReasoning && (payload.max_tokens ?? 0) < 4096) {
payload = { ...payload, max_tokens: Math.max(payload.max_tokens ?? 0, 4096) };
} Type guard
export function isGenerationLengthError(e: unknown): e is GenerationLengthError {
return e instanceof GenerationLengthError;
} Try / catch
try { for await (const c of stream) render(c); }
catch (e) {
if (isGenerationLengthError(e)) offerRetryWithHigherLimit();
else throw e;
} Prevention
- Scale max_tokens with reasoning effort.
- Offer a UI toggle to disable thinking when limits are tight.
- Never auto-retry a length-limited generation with the same settings.
When it happens
Trigger: A reasoning model with a low max_tokens setting: the reasoning channel fills the budget, finish_reason becomes 'length', sawAssistantContent stays false, and throwIfReasoningOnlyLength() fires at stream end (either [DONE] or clean EOF).
Common situations: Reasoning models (o-series / thinking modes) with max_tokens copied from a non-reasoning config; long chains of thought eating a 1-2k budget; users enabling thinking on a plan/model with a tight output cap.
Related errors
- {path}: not valid JSON: {exc}
- Generating at {w}x{h}{batch_note} needs about {total / 1024:
- ChatGPT returned a malformed stream.
- ChatGPT Codex generation failed{f' ({code})' if code else ''
- ChatGPT stream ended before completion.
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/e53a30bb64c417c9.
Report an issue: GitHub.