Subagents have no token budget awareness — consume unbounded context then crash
Problem
Subagents (Task tool agents — Explore, Plan, general-purpose, custom) have no awareness of their own token consumption. When a subagent encounters a broad task, it keeps issuing tool calls, reading files, and accumulating context without limit. Once it crosses a threshold (~50k+ tokens), it crashes — typically with classifyHandoffIfNeeded is not defined (tracked separately in #22312, #23307) or a generic failure message.
The crash is a symptom. The root cause is that subagents have no mechanism to:
- Monitor their own token/context usage
- Recognize when a task is growing beyond their budget
- Gracefully return partial results with a summary of what was completed and what remains
Instead, they "go rogue" — reading dozens of files, spawning further searches, expanding scope — until they hit a hard wall and the parent context receives nothing useful back (just an error).
Reproduction
- Dispatch a Task agent with a broad prompt (e.g., "explore how authentication works across the entire codebase")
- The agent starts reading files, grepping, globbing — often 20-40+ tool calls
- Its internal context grows past 50k tokens
- The agent crashes with an error like:
Agent "..." failed: classifyHandoffIfNeeded is not defined- Or a silent failure with no summary returned
- The parent context wasted a turn and received nothing
Expected Behavior
Subagents should have a token budget and a graceful exit path:
- Budget awareness — The subagent knows its token ceiling (configurable, e.g.,
max_tokens: 30000or derived from remaining parent context) - Progressive checkpointing — As the agent works, it accumulates partial results it can return at any time
- Budget warning — At ~80% of budget, the agent stops expanding scope and begins summarizing findings
- Graceful return — At budget limit, the agent returns:
- What it found so far
- What it didn't get to
- Suggested follow-up queries for the parent to dispatch as new agents
- Never crash silently — Even on unexpected failure, partial results should be returned rather than discarded
Current Workarounds
- Set
max_turnslow to limit agent scope — but this is a blunt instrument (turn count != token count, and useful deep work gets cut short) - Break prompts into narrow, specific queries — but this defeats the purpose of having autonomous agents
- Avoid using subagents for broad exploration — but that's their primary use case
Impact
- Wasted parent context — The parent allocates a turn, waits, and gets nothing back
- Lost work — The subagent may have found useful information before crashing, but none of it is returned
- Cascading failures — A failed subagent often triggers the parent to retry, consuming more context on the same doomed approach
- User distrust — Users learn to avoid the Task tool for anything non-trivial, reducing the tool's value
Related Issues
- #22312 —
classifyHandoffIfNeeded is not defined(the crash symptom, not root cause) - #23307 — Same crash affecting built-in agents
- #25815 — Parent context has no way to
/compactduring multi-step turns (compounds this problem)
Environment
- Platform: Windows 11
- Claude Code: latest
- Model: Opus 4.6
- Reproducible across agent types: Explore, Plan, general-purpose, custom
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗