You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Subagent exhausts max-turns fetching context and returns no summary (174K tokens wasted); salvage partial output + inline context #48
A read-only Subagent can exhaust its max-turns limit fetching context and then terminate with no summary — burning real wall-clock and a large token spend while returning nothing useful to the parent. Observed live: a Spec-adherence reviewer subagent ran 1m 8s · ↑173.9K input tokens · 12 tools and stopped with stop:max-turns → (subagent produced no summary).
Observed (live, Opus panel review)
The parent dispatched one Subagent ("Spec adherence check for PR 1626"). Its result card:
✓ Subagent · Spec adherence check for PR 1626
subagent · 1m 8s · ↑173.9K ↓2.7K · 12 tools · stop:max-turns
agentId: subagent-toolu_bdrk_017b8X9i1L4g6FqQs1h5KrP2
[subagent stopped: reached its max-turns limit]
(subagent produced no summary)
The subagent spent all 12 turns / 174K input tokens fetching the PR diff and never reached the actual review before hitting max-turns. The parent then said, verbatim: "The spec subagent hit its turn limit. Let me re-run it with the diff inlined (it's already in my context) so it doesn't burn turns fetching." — i.e. the model itself identified that the child wasted its budget re-fetching context the parent already held.
Why this is a problem
Pure waste. ~1 minute and 174K input tokens produced zero output. At scale (panel of 6 reviewers), that compounds badly.
No partial value on max-turns. The terminal render is (subagent produced no summary) — the parent gets nothing actionable, not even "here's what I found in the turns I had." A max-turns stop currently yields an empty deliverable.
Avoidable root cause. The child re-fetched a diff the parent already had in context. The harness has no mechanism nudging the parent to inline context for read-only children, and no guidance steering subagents away from expensive fetches when the budget is tight.
Possible directions (discussion — no fix proposed)
Salvage partial output on max-turns. When a subagent stops on max-turns (or any non-StopEndTurn benign terminal), prompt it for a one-shot "summarize what you found so far" wrap-up turn before returning, so the parent gets something rather than (produced no summary). (Mirrors how the team lead is driven to a real synthesis even when budget-stopped.)
Encourage context inlining for read-only children. Surface guidance (Subagent tool description / skill prompt) that the parent should pass excerpts it already holds instead of having each child re-fetch — especially for fan-out reviews where N children would each re-fetch the same diff.
Right-size the default per-subagent turn budget for fetch-then-act tasks, or make the budget-exhaustion message model-facing enough that the parent reliably switches strategy (here it did, but only after the waste).
Salvage partial output — 0d878cf: a free-text child stopping on StopMaxTurns/StopMaxToolCalls with blank final text gets ONE bounded wrap-up turn (salvageEmptyLimitStop, Limits.MaxTurns=1 pinned, same tighten-only token ceiling, original stop reason preserved) so the parent gets a deliverable instead of "(subagent produced no summary)".
Context-inlining guidance — the Subagent tool description now instructs: "Inline context you already hold (e.g. a diff, file contents, prior findings) directly in prompt rather than making the subagent re-fetch it — that saves its limited turn/tool budget for the actual task" (engine/agent/subagent.go).
Activity
feat(agent): salvage a partial summary when a subagent hits its turn/…
JAORMX commentedon Jun 12, 2026
All three directions shipped on main:
salvageEmptyLimitStop, Limits.MaxTurns=1 pinned, same tighten-only token ceiling, original stop reason preserved) so the parent gets a deliverable instead of "(subagent produced no summary)".promptrather than making the subagent re-fetch it — that saves its limited turn/tool budget for the actual task" (engine/agent/subagent.go).fix(agent): salvage budget-stopped subagents + discourage self-capping