{"record":{"id":"494959e4436ced30","repo":"zed-industries/zed","slug":"the-agent-reached-the-maximum-number-of-tokens","errorCode":null,"errorMessage":"The agent reached the maximum number of tokens.","messagePattern":"The agent reached the maximum number of tokens\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/agent/src/agent.rs","lineNumber":3536,"sourceCode":"                    } else {\n                        thread.update(cx, |thread, cx| thread.cancel(cx)).await;\n                        Err(anyhow!(\n                            \"The agent is nearing the end of its context window and has been \\\n                             stopped. You can prompt the thread again to have the agent wrap up \\\n                             or hand off its work.\"\n                        ))\n                    }\n                }\n            };\n            let discard_partial_output = matches!(\n                &response,\n                Ok(Some(response)) if response.stop_reason == acp::StopReason::Cancelled\n                    || response.stop_reason == acp::StopReason::Refusal\n            );\n            let result = match response {\n                Ok(Some(response)) => match response.stop_reason {\n                    acp::StopReason::Cancelled => Err(anyhow!(\"User canceled\")),\n                    acp::StopReason::MaxTokens => Err(anyhow!(\"The agent reached the maximum number of tokens.\")),\n                    acp::StopReason::MaxTurnRequests => Err(anyhow!(\"The agent reached the maximum number of allowed requests between user turns. Try prompting again.\")),\n                    acp::StopReason::Refusal => Err(anyhow!(\"The agent refused to process that prompt. Try again.\")),\n                    _ => thread.read_with(cx, |thread, _cx| {\n                        thread\n                            .last_message()\n                            .and_then(|message| {\n                                let content = message.as_agent_message()?\n                                    .content\n                                    .iter()\n                                    .filter_map(|content| match content {\n                                        AgentMessageContent::Text(text) => Some(text.as_str()),\n                                        _ => None,\n                                    })\n                                    .join(\"\\n\\n\");\n                                if content.is_empty() {\n                                    None\n                                } else {\n                                    Some(content)","sourceCodeStart":3518,"sourceCodeEnd":3554,"githubUrl":"https://github.com/zed-industries/zed/blob/916fc2b8cb3a815cbef4a3b40e13081be72036b6/crates/agent/src/agent.rs#L3518-L3554","documentation":"The Zed agent's subagent runner maps the ACP (Agent Client Protocol) StopReason::MaxTokens to this error: the model stopped mid-task because it exhausted the per-run token budget before producing a usable final answer. It is surfaced to the parent thread as an anyhow error, optionally with the subagent's partial output appended.","triggerScenarios":"A subagent prompt requires so many model requests/tokens (large tool outputs, huge file reads, long generations) that the backend reports stop_reason=MaxTokens instead of EndTurn. Occurs in Agent::run via the acp_thread send/response loop.","commonSituations":"Asking the subagent to summarize or rewrite a very large codebase section in one turn; runaway tool-call loops consuming the context window; model with small context limit handling an oversized prompt.","solutions":["Break the task into smaller prompts and run the subagent multiple times","Enable context auto-compaction so the thread is compacted before limits are hit","Reduce inputs: read fewer/smaller files or trim the prompt given to the subagent","Switch to a model with a larger context window","Prompt the thread again to let the agent wrap up or hand off its partial work"],"exampleFix":"// before: one oversized subagent prompt\nthread.send(\"Rewrite all files in crates/ui in one go\");\n\n// after: scoped, smaller task\nthread.send(\"Rewrite only crates/ui/src/button.rs, summarizing the rest\");","handlingStrategy":"try-catch","validationCode":"// before prompting, check token headroom\nlet usage = thread.read(cx).latest_token_usage();\nif usage.map_or(false, |u| u.ratio() > 0.8) {\n    // compact or start a new thread before sending a large task\n}","typeGuard":null,"tryCatchPattern":"match subagent_result {\n    Err(e) if e.to_string().contains(\"maximum number of tokens\") => {\n        // split the task and retry with a smaller scope\n    }\n    other => other?,\n}","preventionTips":["Keep subagent prompts small and narrowly scoped","Enable context auto-compaction on threads","Monitor token usage ratio before dispatching large tasks","Prefer models with larger context windows for big refactors"],"tags":["agent","llm","context-window"],"backgroundTag":"value-out-of-range","analyzedSha":"916fc2b8cb3a815cbef4a3b40e13081be72036b6","analyzedAt":"2026-09-19T19:09:50.599Z","contentChangedAt":"2026-09-19T19:09:50.599Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}