[BUG] Agent view daemon: stale "done" sessions accumulate uncleaned, causing synchronous blocking cleanup that stalls session spawn/switch
Preflight Checklist
- [x] I have searched existing issues — related but not exact: #71459 (confirms a "memory-pressure reaping" design pattern exists for background shell jobs, different subsystem), #68394 (Windows: agent session processes not reaped at all — opposite-direction symptom), #70252 (terminated agents persist in the agent list, no cleanup mechanism). None describe the spawn/switch-blocking behavior below.
- [x] This is a single bug report
- [x] I am using the latest version of Claude Code
What's Wrong?
The background-agent daemon (claude agents / agent view) accumulates completed ("done") sessions without proactively cleaning them up. When the daemon's internal low-memory heuristic trips, it synchronously retires/reaps settled sessions before proceeding — and this blocking cleanup is visible to the user as a multi-second stall (~15-20s observed) in at least two places:
- Spawning a new session ("open new session" from agent view) — the new session sits in a delayed/stalled loading state; typed commands (e.g.
/rename) are accepted but don't echo or update the UI until cleanup finishes. Oddly, once it does unblock, the original dispatch prompt appears to get processed/echoed after the interim command typed during the stall, suggesting queued messages are replayed out of order once the session unblocks. - Switching between existing sessions in agent view — produces a "waiting for session to redraw" message for a similarly extended period.
The low-memory heuristic appears miscalibrated. At the exact moment it fired (logged "low memory (120MB free)"), memory_pressure reported the system at 41% free/available system-wide on a 32GB machine — not remotely under real memory pressure. This suggests the check reads raw free pages rather than actually-available memory (free + reclaimable/purgeable) — macOS deliberately keeps raw free pages low via aggressive disk caching, so a raw-free-pages check will trigger constantly on macOS regardless of real headroom.
Separately, claude agents --json --all showed a large majority of all tracked sessions already in state: done — apparently never proactively reaped after completion, only lazily/reactively when the daemon needs memory for a new spawn. The larger this backlog grows, the more blocking cleanup work lands at the least convenient moment (exactly when the user is trying to do something).
Steps to Reproduce
- Use
claude agents/ agent view regularly over an extended period, accumulating many completed background sessions that aren't manually cleaned up. - Run
claude agents --json --all— observe a large number ofstate: donesessions still tracked. - Dispatch a new session ("open new session") or switch between existing sessions in agent view.
- If the daemon's low-memory check trips at that moment, observe a multi-second (10-20s+) stall: new sessions appear delayed/stalled with no immediate echo of typed input; switching sessions shows "waiting for session to redraw."
- Check
~/.claude/daemon.logaround the same timestamp for a[bg] bg: low memory (NNNMB free) — retiring settled workers before spawning <id>line correlating with the stall.
Evidence
Representative daemon.log excerpt (session IDs are short random hex identifiers, replaced with placeholders — not personally identifying either way):
[bg] bg: low memory (68MB free) — retiring settled workers before spawning <id>
[bg] bg spawned <id> (fleet)
[bg] bg: low memory (86MB free) — retiring settled workers before spawning <id>
[bg] bg spawned <id> (fleet)
[bg] bg: low memory (105MB free) — retiring settled workers before spawning <id>
[bg] bg spawned <id> (fleet)
This pattern recurred 27 times in a single day in my logs, with reported "free" values ranging from 68MB to ~350MB.
At the time of one of these events, memory_pressure reported:
System-wide memory free percentage: 41%
— on a 32GB machine, i.e. not under real memory pressure by any conventional measure.
claude agents --json --all at time of investigation:
Total tracked sessions: 81
state=done: 78
state=blocked: 2
state=working: 1
Expected Behavior
- The low-memory check should use an accurate available-memory metric (free + reclaimable/purgeable pages), not raw free pages — especially on macOS, where raw free pages are intentionally kept low by the OS's disk cache.
- Completed (
done) sessions should be proactively reaped shortly after completion or on a schedule, rather than accumulating indefinitely and only being cleaned up reactively. - Any necessary retirement/cleanup work triggered by a user action (new session spawn, session switch) should happen asynchronously rather than blocking that action — or at minimum the UI should clearly communicate that cleanup is in progress rather than appearing to silently hang.
Environment
- Claude Code CLI 2.1.198
- macOS 26.5.2 (build 25F84), Apple Silicon
- 32GB RAM;
memory_pressurereporting 41% free/available at time of stall - Heavy
claude agents/ background-agent usage over an extended period, resulting in dozens of accumulateddonesessions
Related
- #71459 — confirms a similar "memory-pressure reaping" design pattern exists elsewhere in the codebase (background shell jobs, opt-out via
CLAUDE_CODE_DISABLE_BG_SHELL_PRESSURE_REAP) — possibly a variant of the same subsystem applied here to full agent-view sessions. - #68394 — opposite-direction symptom on Windows (sessions not reaped at all, accumulating unboundedly) — may share a root cause in when/how the reaping logic runs.
- #70252 — terminated agents persist in the agent list with "no cleanup mechanism," same general accumulation theme.