[BUG] Multiple background agents completing simultaneously overflow main context — API returns empty response
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
When multiple background agents (via Agent tool with run_in_background: true) complete near-simultaneously, their combined output is injected into the main conversation context in a single turn. This causes context window overflow (100%) before auto-compaction can trigger. The API then returns an empty/malformed response (HTTP 200 with no content), rendering the entire session unusable with no recovery except /clear.
There is no flow control between background agent completion and main context injection:
- No output size budget: Each agent's full result is injected without checking whether the main context has room
- 2. No serialization of agent results: Multiple agent completions in the same turn are batched, not queued
- 3. Auto-compaction can't intervene mid-turn: Compaction only runs between turns, so a single oversized turn bypasses it entirely
- 4. No truncation/summarization of agent output: Unlike
TaskOutput(which truncates to 30K chars), the Agent tool injects the full transcript
What Should Happen?
Before injecting agent results, the system should:
- Check context capacity — estimate if injection would overflow
- 2. Run auto-compaction first if near threshold — free up space before injection
- 3. Serialize concurrent completions — inject one agent result at a time with compaction checks between each
- 4. Truncate or summarize if still too large after compaction
Expected: Agent results should be injected safely without overflowing the context window, even when multiple agents complete simultaneously.
Error Messages/Logs
API Error: API returned an empty or malformed response (HTTP 200) — check for a proxy or gateway intercepting the request
Steps to Reproduce
- Start a Claude Code session with moderate context usage (~40-60%)
- 2. Launch 2+ background agents via Agent tool with
run_in_background: true, each returning substantial output (~50-100K tokens each) - 3. Wait for both agents to complete within a short time window
- 4. Both agent results are injected into the main context in the same turn
- 5. Context jumps from ~50% to 100% in one step
- 6. API returns empty response
- 7. Session is stuck — no recovery possible except
/clear(losing all context)
In my case: two background agents (Write 13 interview cards + Rewrite 12 interview cards) completed simultaneously, each consuming ~100K tokens. The main context was overflowed instantly.
Claude Model
Not sure / Multiple models
Is this a regression?
No, this never worked
Last Working Version
_No response_
Claude Code Version
2.1.177
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
This is the convergence point of several related issues that were either closed or remain unresolved:
- #17208 — Proposed
output_modeparameter for Task tool, closed as "not planned" - - #52390 — AUTOCOMPACT_PCT_OVERRIDE not triggering, still open
- - - #53065 — advisor() inflating reported input tokens, still open
- - - - #34556 — Memory loss across compactions
The fundamental problem: background agent results have no flow control when entering the main context. Sub-agents are isolated during execution, but their outputs are injected atomically on completion. When multiple agents finish at the same time, the main thread receives all their outputs in a single turn, bypassing auto-compaction entirely.
Suggested fix priority:
- Short-term: Serialize agent result injection — inject one result at a time, run compaction checks between each
- 2. Medium-term: Add output size budget — estimate tokens before injection, compact first if needed
- 3. Long-term: Add
output_modeparameter to Agent tool (revisit #17208)
Showing cached comments. Read the full discussion on GitHub ↗
7 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
The single most useful thing here, before anyone reaches for
/clear: the completed agents' output isn't actually lost — it's persisted outside the wedged main context, and you can recover it.Each background/subagent runs with its own transcript file, written under the session's project directory (the per-agent
agent-*.jsonlfiles in the transcript dir — exact path varies by version, but they're separate per-agent JSONL files, not part of the main session transcript). When the main session wedges on context overflow, those files are already complete on disk. So the recovery sequence is:/clear, locate the most recentagent-*.jsonlfiles (sort by mtime) under the session's project/transcript dir.assistantmessage — that's the result that was being injected.jqthe last assistant content block out of each file./clear(or restart). You've kept the work;/clearonly discards the wedged main thread, not the agents' output.claude agents(andclaude agents --json) helps here too — it enumerates the background sessions so you can confirm which ones completed and map them to their transcript files.Preventing the overflow in the first place (your mechanism #4 directly): have each background agent write its full result to a file and return only a short summary plus the path. Then what gets injected into the main context is a one-line pointer, not the full transcript, so N simultaneous completions can't sum past the window. It's a prompt-level workaround until there's a real per-agent output budget on the Agent tool — essentially doing by hand what
TaskOutput's 30K truncation does, but under your control.For context, this sits in a documented cluster of "background work silently breaks the main session" reports — token/context burn from background agents, runaway-subagent fan-out, and background control-loss. The common root is exactly what you isolated: no flow control between background completion and main-context injection. Your framing — batch injection in a single turn bypassing between-turn auto-compaction — is the sharpest statement of it I've seen.
(Linux/WSL2 here; the per-agent transcript files behave the same.)
This matches a pattern I've been hitting with multi-agent overnight loops too. The atomic injection model means you cannot have multiple agents completing near-simultaneously without risking a blown context -- there's no way to tell the runtime "serialize these results, check budget before each injection."
The workaround I've been using: cap background agent concurrency to 2, stagger dispatches with a short delay between spawns, and have each agent write its output to a temp file rather than returning a large result inline. The lead then reads and summarizes those files one at a time. It's manual backpressure but it keeps the main context from getting wedged.
What's your concurrency level when this happens? Curious whether 3+ simultaneous completions is the consistent trigger or whether it can happen with just 2.
Both approaches above address the aftermath — @yurukusa on recovering the agents' persisted output, @kcarriedo on why serialized injection is the structural fix. Adding a note on the headroom side.
The reason the atomic injection hits the ceiling is that the main context is already at ~50–75% before the agents complete. If the main context is kept leaner as the agents run, simultaneous injection has more room before overflow.
Cozempic's guard daemon does this: it monitors the main session JSONL and prunes it at a configurable threshold (compressing tool outputs and compaction overhead). For the specific pattern you're describing — background agents all returning near-simultaneously — you'd run the guard with a lower threshold than default:
That keeps the main context baseline lower so that when agents fire simultaneously there's more buffer. In the scenario you described (two ~100K-token agents, ~50% start state), 55% pruning would give you roughly 45% headroom vs. 25%.
Honest caveat: if both agents return ~100K tokens each and you start at 45%, you still overflow. This helps at the margin and prevents the 'already at 75% when agents fire' case, but it doesn't solve the atomic injection problem fundamentally. The real fix is what @kcarriedo described — serialized injection with pre-injection compaction checks — which is what you're asking for.
In my case, the overflow triggered with just 2 simultaneous completions — two background agents (one writing 13 interview cards, one rewriting 12) each returning ~100K tokens. The main context was at ~50% when both completed in the same turn, jumping directly to 100%.
So 2 is enough to trigger it. The key variable isn't the count of agents but the combined output size relative to remaining context headroom. With two ~100K-token results and ~50% headroom, the math is already over the window. Even a single agent returning 100K+ tokens could overflow if the main context is already at 75%+.
That said, 3+ agents completing simultaneously makes it almost guaranteed — there's no realistic context state where 3 × 50-100K tokens fit in the remaining window.
Worth noting for users on non-Anthropic upstreams: models like GLM-5.1 have only 200K context windows (vs. Claude's 200K but with prompt caching headroom). On a 200K window with no caching, a single 50K agent result can overflow from 75%. The problem is even more acute on smaller-window models — your stagger + manual backpressure approach is essentially mandatory there.
@lg320531124 Your math is exactly right — 2 is the threshold, and the key variable is combined output relative to remaining headroom. Two 100K results into 50% headroom: 200K combined + ~430K existing approaches the 1M ceiling. Agent count is nearly irrelevant; it's the simultaneity multiplied by output size that does it.
The only lever available before CC adds a serialization gate on agent result injection is keeping the main context lean as the agents run — if you're at 30% headroom instead of 50% when two 100K agents complete, the same pair of completions fits. That's the headroom argument for pruning JSONL bloat from the main session context while agents are in flight, which is what cozempic's guard daemon does in the background (main context only — subagent contexts are separate). Not a fix, but it buys margin.
Thanks @junaidtitan — agreed, simultaneity × output-size vs. remaining headroom is the cleaner framing than agent count. The guard-daemon approach (pruning main-context JSONL bloat while agents are in flight) is a reasonable stopgap until CC adds a serialization gate on result injection. I'll leave this open for the Anthropic team to weigh the upstream fix.