Tracked background Bash tasks (run_in_background) killed ~30-90s after the owning session's turn ends; Monitor-class and detached processes unaffected

Status Fixed / completed
Reported on v2.1.231
Maintainer reply None cached
Activity 0 comments · opened Aug 18, 2026 · closed Aug 18, 2026

Summary

Harness-tracked background Bash tasks (run_in_background: true) are killed ~30-90 seconds after the owning session's turn ends. Monitor-class tasks and nohup+disown detached processes started at the same moment are unaffected. The regression is episodic across days (clean windows and active windows alternate with no identified config change), but deterministic while active: the kill consistently fires 30-90s after the first genuinely quiet turn end.

Observed on macOS (Darwin 25.5.0), Claude Code versions 2.1.231 through 2.1.234 (still reproducing on 2.1.234 as of 2026-08-17).

Behavior detail

  • Every tracked background Bash task across ALL concurrently running sessions on the machine is affected while the regression is active. Scoreboard at first escalation: tracked bg-Bash 0/8+ survived across 4 sessions; Monitor-class 2/2+ survived; nohup+disown detached 2/2+ survived.
  • Arm/cancel pattern: a tracked canary survived ~11 minutes of intermittent session re-invocations (each new turn apparently cancels the pending kill), then was killed 30-40s after the first quiet turn end. This suggests a kill window armed at turn end and cancelled on re-invocation.
  • A pre-registered discriminating experiment paired a tracked canary with a detached nohup control emitting beats in lockstep: the tracked task was killed between two 15s beats ~30-40s post-turn-end while the detached control ran uninterrupted.
  • Episodic activation: active 2026-08-14 ~18:48Z onward, clean by ~21:00Z the same evening (a 30-minute 120/120-beat tracked canary completed through genuine idle), active again 2026-08-15 ~11:57Z, and again 2026-08-17 (a tracked task running a test chain was killed mid-run ~2 minutes after turn end; rerun completed clean).
  • Onset window on 08-14 contained exactly one identified machine change: a ~/.claude/settings.json mtime bump whose diff is unknown (no prior copy). The machine's only PostToolUse hook was exonerated by code read (wake-only, no kill path, unchanged for weeks). A daemon version boundary (2.1.231 -> 2.1.232) predates onset by ~2h -- recorded but disfavored as the cause since the phenomenon is episodic within a single version.

Not user-initiated (ruled out)

On 2026-08-17 the machine's operator manually killed several high-memory Python processes during a memory-pressure incident. This is ruled out as the explanation for this report: (1) the confirmed kill datums on 08-14 and 08-15 predate that incident; (2) manual kills cannot produce the observed selectivity (tracked bg-Bash dies, paired detached control started at the same instant survives) nor the consistent 30-90s post-quiet-turn-end timing with re-invocation cancelling the window; (3) the manual-kill incident is tracked separately and its process set (high-RSS Python) does not match the affected set (harness-tracked bash loops).

Repro sketch

  1. In a session, run a background Bash task: for i in $(seq 1 120); do echo beat; sleep 15; done with run_in_background: true.
  2. End the turn and leave the session idle.
  3. While the regression is active, the task is killed within ~30-90s of the turn end (the task-completion notification arrives with the loop far from finished).
  4. Repeat with a Monitor-class watch or a nohup ... & disown process: both survive.

Because activation is episodic, a clean run does not falsify -- the discriminating pair (tracked + detached in lockstep) is the reliable instrument.

Impact

Any cross-turn background wait (file watchers, poll loops, long test runs) dies silently at exactly the moment it matters -- when the session goes quiet. Our workaround: Monitor-class or detached-nohup for every cross-turn wait that must survive; tracked background Bash only where loss is harmless.

A detailed timestamped kill log (clock-read timestamps, canary transcripts, discriminator-pair records) is available on request.

View original on GitHub ↗