InboxPoller delivers queued messages without context budget check, causing unrecoverable context overflow

Resolved 💬 7 comments Opened Feb 7, 2026 by vabole Closed Mar 13, 2026

Summary

When a team-lead session goes idle, InboxPoller delivers all queued teammate messages at once without checking whether they fit in the remaining context budget. This can instantly double the token count past the hard limit. The autocompact agent then fails silently (zero output), and the session becomes unrecoverable.

From the user's perspective: the session stops with "Context limit reached", but /context shows 50% free space (101k/200k). Running /compact doesn't help — the same silent failure repeats. There's no indication of what went wrong.

Environment

  • Claude Code: 2.1.34 (bun)
  • Model: claude-opus-4-6 (200k context)
  • Platform: macOS Darwin 25.2.0
  • Session: team-lead with 2 in-process teammates (alpha, bravo)

Root Cause

Three things combine to cause this:

1. InboxPoller bulk-delivers without a token budget check

When the session goes idle, InboxPoller delivers all pending messages in one batch. In this case, 7 queued teammate messages were delivered at once, pushing the token count from 101k to 205k instantly:

06:29:47.423 autocompact: tokens=101029   <- last reading before spike
06:29:47.450 [InboxPoller] Session idle, delivering 4 pending message(s)
06:29:50.175 autocompact: tokens=205296   <- 2x in 3 seconds

2. Compact agent silently produces zero output

The compact agent is forked but immediately finishes without doing any work:

06:29:50.180 Forked agent [compact] received message: type=assistant
06:29:50.180 Forked agent [compact] finished: 1 messages
             totalUsage: input=0 output=0 cacheRead=0 cacheCreate=0
06:29:50.190 ERROR: Conversation too long.

No error is logged from the compact agent itself — it just exits with zero tokens. This happens because the conversation (205k) already exceeds the model's hard limit (200k), so the compact agent can't even start an API call. But this failure is completely silent.

A retry 23 seconds later produces the identical silent failure.

3. /context display shows stale data

After the failure, /context reports:

claude-opus-4-6  101k/200k tokens (50%)
Free space: 63k (31.6%)

The display doesn't reflect the actual 205k payload that caused the failure. The user sees 50% free space and has no way to understand why the session is dead.

Full Timeline

04:52:26 Session starts (209 tokens)
04:55:52 First autocompact succeeds, tokens reset to 161      OK
06:21:28 Second autocompact succeeds, tokens reset to 116     OK
06:22:24 Tokens grow back to ~76k (normal growth after compact)
06:29:44 tokens=100,757 -- session goes idle
06:29:44 [InboxPoller] delivering 3 pending messages
06:29:44 bravo approves shutdown, lifecycle aborted
06:29:45 alpha and bravo removed from team
06:29:47 tokens=101,029 -- session goes idle again
06:29:47 [InboxPoller] delivering 4 more pending messages
06:29:50 TeamDelete called (team cleanup)
06:29:50 tokens=205,296 -- autocompact triggers
06:29:50 compact agent: input=0 output=0 (silent failure)
06:29:50 ERROR: Conversation too long
06:30:13 Retry: compact agent: input=0 output=0 (same failure)
06:30:13 ERROR: Conversation too long (unrecoverable)

Suggested Fixes

Must fix

  • InboxPoller: check token budget before delivering. If delivering queued messages would exceed effectiveWindow, either deliver incrementally (compact between batches) or trigger compaction before delivery.
  • Compact agent: fail loudly. If the conversation exceeds the model's hard limit and compaction can't even start, log an explicit error explaining why, rather than exiting with zero output.

Should fix

  • /context display: show actual payload size. After a "Conversation too long" error, the display should reflect the real token count that caused the failure, not a stale pre-failure reading.
  • Fallback compaction strategy. When the conversation exceeds the hard limit and normal compaction can't work, the system should have a fallback — e.g., truncating the oldest N messages until the conversation fits, then running normal compaction.

Additional Context

  • Earlier compactions in the same session succeeded (tokens=29k reset to 161, tokens=72k reset to 116), confirming autocompact works under normal conditions
  • The background prompt_suggestion agent accumulated ~100k cache tokens over the session (cacheRead grew from 21k to 100k), which may contribute to context pressure
  • In-process teammate contexts log autocompact readings through the same codepath as the main conversation (~17k interleaved with ~100k readings), suggesting context tracking may not be fully isolated

Stack Trace

Error: Conversation too long. Press esc twice to go up a few messages and try again.
    at sj1 (cli.js:3351:934)
    at async Rr4 (cli.js:3436:2536)
    at async EZ (cli.js:3529:7480)
    at async EZ (cli.js:3529:14947)
    at async cli.js:6420:2856
    at async cli.js:6420:4248

Workaround

Until this is fixed, users running agent teams can mitigate by manually running /compact before shutting down teammates, to create headroom for the incoming inbox messages.

View original on GitHub ↗

This issue has 7 comments on GitHub. Read the full discussion on GitHub ↗