{"record":{"id":"76836ecc74d5f208","repo":"alibaba/page-agent","slug":"context-length","errorCode":"CONTEXT_LENGTH","errorMessage":"Response truncated: max tokens reached","messagePattern":"Response truncated: max tokens reached","errorType":"exception","errorClass":"InvokeError","httpStatus":null,"severity":"warning","filePath":"packages/llms/src/OpenAIClient.ts","lineNumber":154,"sourceCode":"\t\t\t\tInvokeErrorTypes.INVALID_RESPONSE,\n\t\t\t\t'Response body is not valid JSON',\n\t\t\t\terror\n\t\t\t)\n\t\t}\n\n\t\tconst choice = data.choices?.[0]\n\t\tif (!choice) {\n\t\t\tthrow new InvokeError(InvokeErrorTypes.INVALID_SCHEMA, 'No choices in response', data)\n\t\t}\n\n\t\t// Check finish_reason\n\t\tswitch (choice.finish_reason) {\n\t\t\tcase 'tool_calls':\n\t\t\tcase 'function_call': // gemini\n\t\t\tcase 'stop': // some models use this even with tool calls\n\t\t\t\tbreak\n\t\t\tcase 'length':\n\t\t\t\tthrow new InvokeError(\n\t\t\t\t\tInvokeErrorTypes.CONTEXT_LENGTH,\n\t\t\t\t\t'Response truncated: max tokens reached',\n\t\t\t\t\tundefined,\n\t\t\t\t\tdata\n\t\t\t\t)\n\t\t\tcase 'content_filter':\n\t\t\t\tthrow new InvokeError(\n\t\t\t\t\tInvokeErrorTypes.CONTENT_FILTER,\n\t\t\t\t\t'Content filtered by safety system',\n\t\t\t\t\tundefined,\n\t\t\t\t\tdata\n\t\t\t\t)\n\t\t\tdefault:\n\t\t\t\tthrow new InvokeError(\n\t\t\t\t\tInvokeErrorTypes.INVALID_SCHEMA,\n\t\t\t\t\t`Unexpected finish_reason: ${choice.finish_reason}`,\n\t\t\t\t\tundefined,\n\t\t\t\t\tdata","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/alibaba/page-agent/blob/d02db1ee7c41f5315beda88bab2fe935c580f662/packages/llms/src/OpenAIClient.ts#L136-L172","documentation":"The model stopped because it hit the max_tokens / output token limit (finish_reason === 'length') before completing a valid response. The full raw response is attached in details, and unlike other errors there is no underlying cause object. For tool-calling agents this usually means truncated, unparseable tool arguments.","triggerScenarios":"invoke() where max_tokens (or the provider's default output cap) is reached: very long tool call JSON cut off mid-argument; max_tokens set low in config; reasoning models spending the budget on hidden reasoning tokens before emitting content.","commonSituations":"Default or user-set max_tokens too small for the task; long structured outputs (big JSON tool inputs); models like o1/gemini-thinking burning tokens on reasoning; combined prompt+completion caps on some providers.","solutions":["Raise or remove max_tokens in the request/config","If the provider has a separate output-token cap, request a higher one","Reduce expected output size: fewer/simpler tools, shorter requested formats","If finish_reason 'length' recurs, catch CONTEXT_LENGTH and re-invoke asking for a continuation or a more compact response"],"exampleFix":"// before\nconst llm = new LLM({ client, maxTokens: 256 })\n\n// after\nconst llm = new LLM({ client, maxTokens: 4096 })","handlingStrategy":"fallback","validationCode":"// keep an eye on prompt+output budget before invoking\nconst approxInputTokens = estimateTokens(JSON.stringify(request.messages))\nif (approxInputTokens + minOutputBudget > modelContextLimit) throw new Error('Prompt too large for safe completion')","typeGuard":"const isContextLengthError = (e: unknown): e is InvokeError =>\n  e instanceof InvokeError && e.code === 'CONTEXT_LENGTH'","tryCatchPattern":"try {\n  return await client.invoke(req)\n} catch (e) {\n  if (isContextLengthError(e)) {\n    return await client.invoke({ ...req, max_tokens: (req.max_tokens ?? 1024) * 4 })\n  }\n  throw e\n}","preventionTips":["Set max_tokens generously for tool-calling tasks (tool JSON is verbose)","Watch token usage fields in responses to detect approaching limits","Trim conversation history aggressively in long agent loops"],"tags":["max-tokens","truncation","finish-reason-length"],"backgroundTag":"max-tokens-exceeded","analyzedSha":"d02db1ee7c41f5315beda88bab2fe935c580f662","analyzedAt":"2026-08-28T19:39:48.634Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}