Skip to content

[Bug]: A background Claude subagent stays running forever when the Claude process exits while its parent is idle #19440

Open

Description

@Vantrongs

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

  1. 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.

  2. When LAUNCHED appears, kill that thread's claude process with kill -9 <pid>. This stands in for a crash or an OOM kill.
  3. 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 1 command became failed. So T3 saw the process exit.
  • The subagent itself stayed running in orchestration_v2_projection_subagents, with no completed_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, finalizeActiveTurnAfterQueryExit ends only subagents that run a workflow (L6209-L6246: subagent.task.workflow === undefined → continue). A plain background Agent subagent keeps its running status. endSubagentCallsOfClosedQuery then ends its open calls, which matches the failed step above.
  • Nothing ends it later. Its task_notification would have come from the dead process. stopSubagent refuses 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

  1. added
    bugSomething is broken or behaving incorrectly.
    needs-triageIssue needs maintainer review and initial categorization.
    on Oct 14, 2026
  2. juliusmarminge commented on Oct 14, 2026

    @juliusmarminge
    Member

    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, finalizeActiveTurnAfterQueryExit in apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts only ends running subagents that have a workflow. A plain background Agent subagent hits continue and stays running. After that, nothing can end it. Its task_notification would have come from the dead process, and stopSubagent rejects 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 buffered task_notification should still decide the outcome, the same way that loop already handles workflows.

  3. added
    acceptedfeature request accepted
    via-triageFiled through npx t3 triage
    and removed
    needs-triageIssue needs maintainer review and initial categorization.
    on Oct 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    acceptedfeature request acceptedbugSomething is broken or behaving incorrectly.via-triageFiled through npx t3 triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions