[BUG] Multiple background agents completing simultaneously overflow main context — API returns empty response

Status Closed — not planned
Reported on v2.1.177
Maintainer reply None cached
Activity 8 comments · opened Jun 15, 2026 · closed Aug 29, 2026

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:

  1. No output size budget: Each agent's full result is injected without checking whether the main context has room
  2. 2. No serialization of agent results: Multiple agent completions in the same turn are batched, not queued
  3. 3. Auto-compaction can't intervene mid-turn: Compaction only runs between turns, so a single oversized turn bypasses it entirely
  4. 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:

  1. Check context capacity — estimate if injection would overflow
  2. 2. Run auto-compaction first if near threshold — free up space before injection
  3. 3. Serialize concurrent completions — inject one agent result at a time with compaction checks between each
  4. 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

  1. Start a Claude Code session with moderate context usage (~40-60%)
  2. 2. Launch 2+ background agents via Agent tool with run_in_background: true, each returning substantial output (~50-100K tokens each)
  3. 3. Wait for both agents to complete within a short time window
  4. 4. Both agent results are injected into the main context in the same turn
  5. 5. Context jumps from ~50% to 100% in one step
  6. 6. API returns empty response
  7. 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_mode parameter 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:

  1. Short-term: Serialize agent result injection — inject one result at a time, run compaction checks between each
  2. 2. Medium-term: Add output size budget — estimate tokens before injection, compact first if needed
  3. 3. Long-term: Add output_mode parameter to Agent tool (revisit #17208)

View original on GitHub ↗

7 Comments

github-actions[bot] · 2 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/26041
  2. https://github.com/anthropics/claude-code/issues/24341
  3. https://github.com/anthropics/claude-code/issues/25714

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

yurukusa · 2 months ago

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-*.jsonl files 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:

  1. Before /clear, locate the most recent agent-*.jsonl files (sort by mtime) under the session's project/transcript dir.
  2. Extract each agent's final assistant message — that's the result that was being injected. jq the last assistant content block out of each file.
  3. Then /clear (or restart). You've kept the work; /clear only discards the wedged main thread, not the agents' output.

claude agents (and claude 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.)

kcarriedo · 2 months ago

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.

junaidtitan · 2 months ago

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:

cozempic guard --session $SESSION_ID --threshold 55

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.

lg320531124 · 2 months ago

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.

junaidtitan · 2 months ago

@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.

lg320531124 · 1 month ago

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.

Showing cached comments. Read the full discussion on GitHub ↗