Repository navigation
[Bug]: A background Claude subagent stays running forever when the Claude process exits while its parent is idle #19440
Description
Before submitting
- I searched existing issues and did not find a duplicate.
- I included enough detail to reproduce or investigate the problem.
Area
apps/server
Steps to reproduce
- In a Claude thread, send:
Call the Agent tool once: subagent_type "general-purpose", run_in_background true, description "Repro bg", prompt: "Make 3 Bash tool calls strictly one after another, one tool call per message, waiting for each result before the next. Each runs exactly: python3 -c 'import time; time.sleep(60)' with the description 'Step N' (N = 1..3). After the third result, reply with exactly: READY_BG". After the Agent call returns, reply with exactly LAUNCHED and stop. Do nothing else.
- When LAUNCHED appears, kill that thread's
claudeprocess withkill -9 <pid>. This stands in for a crash or an OOM kill. - Watch the subagent's card in the parent and the subagent's thread.
Expected behavior
The subagent ends as failed, since the process that ran it is gone. Its card and thread stop showing it as working, and the parent no longer waits for it.
Actual behavior
From my run on 0.0.46-nightly.20261014.3093:
- At the kill (11:34:14.04 UTC), the subagent's running
Step 1command becamefailed. So T3 saw the process exit. - The subagent itself stayed
runninginorchestration_v2_projection_subagents, with nocompleted_at. That was still so several minutes later, after all three steps would have finished. In a second run, where the scope was OOM-killed during step 2, the card still reads "Running Step 2".
In real use, the kernel OOM-killed a test binary of a background subagent while the parent was idle. Agent scopes use OOMPolicy=stop, so systemd then stopped the whole Claude scope (the scope policy is discussed on #19367). The CLI had already delivered the tool's Exit code 137 result, and nothing came after it. Two and a half hours later, the subagent's thread still showed "Working for 2h 35m" over its last command, and the parent was still listed as Waiting. All of the subagent's items were completed or failed, and its thread was idle. Only the subagent record was still running. That looks like a subagent that works but stopped showing its progress.
Cause, as far as I can tell from the source at f99b202:
- When the CLI's message stream ends while the root has no active turn,
finalizeActiveTurnAfterQueryExitends only subagents that run a workflow (L6209-L6246:subagent.task.workflow === undefined→continue). A plain backgroundAgentsubagent keeps itsrunningstatus.endSubagentCallsOfClosedQuerythen ends its open calls, which matches thefailedstep above. - Nothing ends it later. Its
task_notificationwould have come from the dead process.stopSubagentrefuses a subagent with no live owning query (L9217-L9227). fix(server): settled and idle-released threads no longer stay Waiting #19355 clears the background roster when a session is released, but it doesn't touch subagent records.
One way to fix it: on process exit, end every subagent that process ran and that is still running, as failed (or cancelled after Stop), the same way that loop already ends workflows. Its buffered task_notification, if any, would still decide the outcome.
Related: #16484 (a background subagent's live progress while the parent is idle) and #17154 (subagents left running after a delegated task is cancelled).
Impact
Major degradation or frequent failure
Version or commit
0.0.46-nightly.20261014.3093 (107f602); main at f99b202 has the same finalizeActiveTurnAfterQueryExit
Environment
Desktop app on Linux (NixOS, systemd 261), Claude Code 2.1.296
Logs or stack traces
No response
Screenshots, recordings, or supporting files
No response
Workaround
No response
Activity
juliusmarminge commentedon Oct 14, 2026
Note
Grok responding on behalf of Julius.
Confirmed on main: this is a bug, and it's separate from the other stuck-subagent reports.
When the Claude query exits while the root has no active turn,
finalizeActiveTurnAfterQueryExitinapps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.tsonly ends running subagents that have aworkflow. A plain backgroundAgentsubagent hitscontinueand staysrunning. After that, nothing can end it. Itstask_notificationwould have come from the dead process, andstopSubagentrejects it with "no live owning query", so Stop doesn't work either.This isn't a duplicate:
Likely fix: on process exit, end every subagent from that process that is still
running(not just workflows) as failed, or as cancelled if Stop was requested. Any bufferedtask_notificationshould still decide the outcome, the same way that loop already handles workflows.