[BUG] Auto-update daemon transition reaps a live session's in-flight headless background tasks (status 'killed', no attribution) — Linux, 2.1.210→2.1.211
Environment
- Claude Code on Linux, native install
- A long-lived daemon-managed background session (agents view job), process running v2.1.210
- Auto-update installed v2.1.211 while the session was mid-work
What happened
Two background tasks spawned by the session's Bash tool (each a timeout 5400 claude -p --model sonnet ... headless run, launched with run_in_background) were killed 1-3 minutes after launch, with task status "killed", zero bytes of output, and no TaskStop issued by the session. A third identical launch the next morning completed normally.
Forensic timeline (all times local):
- 02:07 first headless task launched
- 02:10 the auto-updater finished installing the v2.1.211 binary (
~/.local/share/claude/versions/2.1.211mtime is exactly 02:10) - ~02:10 first task killed; 02:10-02:11 second task launched
- 02:11:10 daemon log:
[supervisor] another daemon is already running (pid=..., version=2.1.211, origin=transient; an on-demand daemon never displaces a running one)followed immediately by[bg] bg orphan-spare reap: 1 - ~02:12 second task killed
- No OOM (plenty of free memory), no timeout (both tasks were minutes into a 90-minute budget), nothing in the system journal
Collateral pattern: the session itself and a long-running Monitor task (armed hours earlier) survived untouched. Only the freshly-spawned headless child processes died. An ephemeral, never-requested task also flashed in and out of the session's task directory during the same window, which I take to be the updater/daemon machinery itself.
Reading
During the auto-update daemon transition, the new (or surviving) daemon's orphan/spare reaping appears to sweep up in-flight claude -p child processes that belong to a live session's background tasks, treating them as orphans. The session gets a "killed" task notification with no attribution, which reads exactly like the unexplained kills in #76249.
Related, but not the same shape: #73670 (supervisor shuts down for auto-upgrade and never restarts, workers watchdog-killed), #66358 (post-update version skew orphans old workers), #73332 (workers reaped mid-work on macOS). In our case the daemon transition itself went fine and the session survived; the casualties were the session's own in-flight headless child tasks.
Expected
In-flight background tasks owned by a live session should survive an auto-update daemon transition (or at minimum be terminated with an attributable reason surfaced to the session, so the agent does not have to forensically reconstruct what killed its work).
Suggestion
- Exempt processes that are registered children of live session tasks from orphan-spare reaping during the update transition, or
- Hand them over to the new daemon the way adopted sessions are, or
- If they must die, deliver a task notification that names the updater/daemon transition as the cause.
Showing cached comments. Read the full discussion on GitHub ↗
3 Comments
Follow-up with new evidence from the same host, which broadens the picture beyond the auto-update transition:
A second kill wave hit today at 17:13-17:21 local with NO update in play (no new binary since the 02:10 one, daemon log silent for hours). Three registered background tasks were stopped 2-5 minutes after launch, including a trivial 30-second-sleep watcher loop, so the trigger is not the task's content or cost. Two control datapoints from the same window:
setsid-detached copy of the identical killed workload ran to completion untouched while its registered twin died. Registration with the task system is the fatal ingredient.This looks like the same family as #76974 (sporadic SIGKILL by task supervision) and #76942 (kills appearing only after a session runs long). Consistent with the latter: this session's job is 12 days old and the waves started after the process had been up ~11h, getting denser at ~26h. The auto-update daemon transition in my original report may be an aggravator or one trigger among several rather than the sole cause.
Practical impact for long-lived agent sessions is significant: in-flight work dies silently mid-task with status "killed" and no attribution, and the workaround (detaching work from the task system) costs the completion-notification machinery. A reap/stop audit line naming the killer (supervisor, watchdog, stop-routing, update transition) would make this class diagnosable in the field.
New datapoint that isolates the collateral-stop mechanism from the process-age and version-skew vectors this issue documented so far, and cross-references #76249 (which looks like the same underlying reap).
Setup: daemon and session both on 2.1.211 (no skew), daemon ~22h old (no long-lived-process factor), Linux, healthy memory (7.7Gi available).
Sequence (UTC, from the session transcript):
Timeout, OOM, and the age/skew vector are all excluded (50s of a 45m budget; free memory; fresh aligned daemon). This looks like stop routing inside the shared per-job daemon task registry occasionally reaping a sibling, which matches #76249's no-TaskStop repro on 2.1.206: the registry reap may be the common mechanism, with TaskStop acting as one trigger among several.
Workaround we use for load-bearing watchers: launch them registry-independent (setsid nohup ... &, polling an output file) whenever a TaskStop may be issued in the same window, and keep all watchers idempotent so a reap never loses state.
Thanks for the detailed timeline — I tried to reproduce this on current released builds.
Setup: a daemon-managed background session on 2.1.210 (your original version) with an in-flight background task (
run_in_background, 5-minute command), then an update to 2.1.233 installed mid-task. Note: 2.1.230 is no longer downloadable from the installer, which is why I started from 2.1.210.The update was detected within seconds and the background service restarted onto the new version while the task was running. In three trials (session mid-turn, idle, and idle with nothing attached), the in-flight task kept running, completed on schedule, and produced its full output — it was never marked "killed". A control run without an update also completed.
Several background-service reliability fixes around updates shipped shortly after the 2.1.211 build you hit (see the 2.1.203–2.1.217 changelog entries about background sessions and updates), and current versions deliberately avoid restarting a session that has work in flight.
This looks fixed in current releases, so I'm closing it. If you see a background task killed around an auto-update on 2.1.233 or later, please reopen with the new timeline.
🤖 Generated with Claude Code