Skip to content

[Bug]: Nested Claude subagents stay Running in the UI after their parent subagent hits the usage limit, while the thread list reports them idle #19993

Open

Description

@UkrainianCitizen

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

Not sure

Steps to reproduce

Observed once on 2026-10-15. Not yet reproduced on purpose.

  1. In a Claude thread, the root agent launches a native Claude subagent (Agent tool) as a worker.
  2. The worker launches two native subagents of its own (two review agents, so spawn depth 2).
  3. About 9 seconds after the two review agents start, the worker hits its Claude session usage limit and stops.
  4. Look at the Lineage panel, the subagent group in the transcript, and the composer.

Expected behavior

When a subagent's parent stops (on a session limit or for any other reason) and the subagent ends, the UI shows the subagent as stopped or idle, matching what the thread list reports. The "Waiting on N subagents" bar clears.

Actual behavior

T3's own thread list and its UI disagree about the two review agents.

  • t3_thread_list (MCP tool, includeSubagents: true) reports both review agents with status idle, latestRunId: null, and updatedAt 9 seconds after createdAt.
  • The Lineage panel shows "2 running", with both agents at 1.1h and the timers still counting.
  • The subagent group in the transcript shows "2 working", with each agent marked "Running".
  • The composer shows "Waiting on 2 subagents ... Stop".

Neither the root agent nor the worker could stop them. Claude Code's TaskStop returned "No task found" for their IDs, and the worker held no IDs for them.

A guess at the cause, not verified: the worker ended before the review agents' finish events reached T3, so the UI never received a terminal status for them.

Related reports with the same symptom and a different trigger: #19440 (Claude process exits while the parent is idle), #16355 (nested subagent completes during a user turn), #18910 (completion arrives but is not applied), #17847 (stopped notification after the session ended). Here the trigger is a parent subagent stopped by a usage limit while its own subagents had just started.

Impact

Minor bug or occasional failure

Version or commit

T3 Code (Nightly) 0.0.46-nightly.20261014.3118

Environment

macOS 27.0.1, desktop app, Claude provider, Claude Code 2.1.300

Logs or stack traces

No response

Screenshots, recordings, or supporting files

Screenshots of the Lineage panel, the transcript subagent group and the composer bar are available on request.

Workaround

No response

Activity

  1. juliusmarminge commented on Oct 15, 2026

    @juliusmarminge
    Member

    Note

    Grok responding on behalf of Julius.

    Thanks for the detailed report. I checked it against the related issues before deciding where it belongs.

    Why this isn't a duplicate of #19440 / #19464: that fix settles background agents when the Claude CLI process exits. On main, a rejected rate_limit_event is handled as a pause ("Rejected windows pause the SDK without ending its turn"), so a usage limit by itself shouldn't trigger that process-exit cleanup. #16355 and #18910 are about a completion that does arrive; here it looks like the review agents' end never arrived at all.

    What the code shows: subagents started by another subagent (spawn depth > 1) are tracked separately, and their end is reported by Claude to the subagent that started them, not to the root. I didn't find anything that marks those depth-2 subagents as ended when their owning subagent stops before reporting their end. That fits what you saw, but this was seen once and not reproduced, so I can't confirm that path yet.

    To move this forward, could you:

    1. Share the server log for that thread around the time the worker hit the limit (the task_started / task_notification events for the two review agents, and whether the worker's own task got a terminal notification).
    2. Say whether the Claude process stayed up after the limit, or exited/restarted (if it exited, this is [Bug]: A background Claude subagent stays running forever when the Claude process exits while its parent is idle #19440 after all).
    3. Attach the Lineage panel / composer screenshots you mentioned.
    4. Try again on the latest nightly if you can reproduce it.
  2. UkrainianCitizen commented on Oct 15, 2026

    @UkrainianCitizen
    Author

    Second reproduction on 2026-10-15. It adds three things: the stuck child was itself rate-limited and then resumed through Claude Code's SendMessage, the UI Stop button cannot clear the stale "running" entry, and T3's own API says the child never had a run. The depth-1 parent stayed alive throughout, so this case does not fit the guess in the issue body.

    Steps

    1. The root thread launches a native subagent (Opus, Agent tool, background).
    2. That subagent launches three Sonnet subagents in parallel (spawn depth 2), titled "Worker 1" to "Worker 3".
    3. At 13:42 UTC all three hit the session limit (HTTP 429, rate_limit) right after their first prompt.
    4. After the reset, the depth-1 subagent resumes each worker with SendMessage, which keeps the same agent ID.
    5. All three finish in Claude Code. Worker 3's transcript (subagents/agent-<id>.jsonl) ends with its final message at 18:00:04 UTC, and its parent acts on the completion.

    Observed state for Worker 3

    • t3_thread_read: status: "idle", runCount: 0, latestRunId: null, activeRunId: null, itemCount: 3, updatedAt 17:46:25 UTC. The items are the prompt, "You've hit your session limit", and "Agent terminated early due to an API error ... rate_limit". Nothing from the resumed run.
    • Lineage: "1 running" for 1.3h and counting.
    • Composer: "Waiting on subagent Worker 3: full test suite after rebase" with Stop.
    • Clicking Stop does nothing. t3_thread_interrupt returns {"runId":null,"status":"no_active_run"}.

    Expected

    Either the resumed run's items and completion land in the child thread, or Stop clears a "running" entry whose child thread has no active run.

    Open question

    Workers 1 and 2 took the same path and do not show as running. I don't know why only Worker 3 is stuck. Two differences, neither confirmed as the cause: it finished at 18:00 UTC, between the other two (17:49 and 18:07 UTC), and Worker 3's parent was blocked in a long foreground Bash call when its completion arrived.

    Screenshots are available on request.

  3. UkrainianCitizen commented on Oct 15, 2026

    @UkrainianCitizen
    Author

    Third reproduction on 2026-10-15, in a separate thread with the same app, project and Claude account. It rules out rate limits, resume and spawn depth 2 as required conditions, and the parent never stopped first.

    Setup

    The root session spawned one Sonnet subagent with Claude Code's Agent tool, in the background, at spawn depth 1. Its transcript has no rate_limit or API error entries. It was never resumed with SendMessage.

    Timeline (UTC)

    • 17:45:59 the subagent starts.
    • 17:49:47 its last Bash call, an rm cleanup and a rerun.
    • 17:54:13 df -h / reports the root volume 100% full, 117 MiB free. The transcript ends with an API request at that second and no response.
    • 17:54:41 the root session receives <task-notification> with <status>completed</status>, summary Agent "Run title-gap check matrix" finished. It kept writing until at least 18:24.

    Observed state

    • t3_thread_list for the child: status: "idle", latestRunId: null, itemCount: 12, updatedAt 17:54:05, 36 s before the parent got the completion.
    • The child thread shows "Working for 1h 23m 24s" with "Running rm" as its last item. Stop does nothing.

    Confound

    The disk was full when the subagent ended. Its own final message never reached its transcript, and T3 may have failed to persist the end event for the same reason. Free space has since recovered to 96 GiB. I can't say whether the disk caused this.

    Your questions

    • Question 2: the Claude processes stayed up here.
    • Screenshots of all three stuck entries are saved. I'll attach them from the browser.
    • I can send the server log for these windows if you tell me where T3 writes it.
  4. voida6 commented on Oct 17, 2026

    @voida6
    Contributor

    I traced the nested path on main (8653c8f) and have a failing adapter test for one piece of it.

    What happens while the root turn is idle. A depth-2 task_started that arrives with no active root turn is buffered for the next wake turn (ClaudeAdapterV2.ts, idle branch around L6517-6560). While a start for that task is buffered, its task_notification is also deferred (canApplyOutcome requires !hasBufferedStart, from #18778). Nested notifications never open a continuation, so the deferred outcome is applied only when something else wakes the root, normally the owning subagent's own completion. Until then, the worker's state doesn't move.

    The test: the root goes idle with a background depth-1 owner. The owner launches a depth-2 worker, which finishes, returns its tool result, and the owner keeps working. No subagent.updated is emitted for the worker at all. The existing test "keeps a nested subagent's launch in order while the root turn is idle" covers the later replay, once the owner finishes and wakes the root.

    How this could fit the second report. Worker 3 was shown and then got stuck, which points to a resume rather than a first launch. A SendMessage resume emits a fresh task_started. If that arrived while the root was idle, it was buffered, and the worker's completion was deferred behind it. If the wake that should replay it never happened (for example the jammed continuation gate in #20430), the entry stays "running". I haven't reproduced the resume variant itself, so treat that as a hypothesis.

    Already covered elsewhere:

    Neither touches the idle nested deferral.

    Possible fix. For a nested task, apply the buffered start and the outcome immediately in the idle branch, since no wake turn will replay them on its own. Happy to send that with the test if this direction looks right.

    Sent by Ravdeep's agent: Claude Opus 5.5 in Claude Code, running in T3 Code.

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

    needs more infoInitial triage showed no bug. Awaiting more infovia-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