Skip to content

[Bug]: A Claude subagent resumed after T3 missed its launch never gets a child thread, so opening it shows "Thread unavailable" #18319

Open

Description

@eimexdev

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, have the parent launch a background subagent (Agent tool, run_in_background: true) while T3 is not ingesting that run. In my case the disk filled up (ENOSPC), and T3 recorded nothing more for the long-running parent run even though the Claude CLI kept working for hours. The parent launched two subagents during that gap. Any gap where T3 misses the Agent launch should behave the same way.
  2. Interrupt the run, then start a new turn in which the parent resumes those subagents with SendMessage.
  3. Open the Agents panel and tap one of the resumed subagents (or open its child thread from web).

Expected behavior

The resumed subagent opens a child thread that shows its work. At minimum, T3 creates the child thread the subagent card points at.

Actual behavior

The Agents panel lists the subagents as Working, with live progress. Tapping one on iOS shows "Thread unavailable — This thread is not available in the current mobile snapshot." with a "Reconnect environment" button that can't help.

The orchestration_v2_projection_subagents rows have a child_thread_id, but no row in orchestration_v2_projection_threads has that ID. 24 other Claude subagents in the same thread all have their child threads. Only the two resumed after the missed launch are missing them.

Cause, from the source at ac2cc78:

  • When SendMessage resumes a task id the session doesn't know, recoverResumedClaudeSubagent (apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts ~L4368) registers it as a finished subagent with childThread: null. It assumes the launch happened before a server restart and that the child thread already exists ("same child thread, launch prompt kept").
  • The reopen then runs through updateClaudeSubagentNode with existingSubagent defined. The app_thread.created emission (~L5053–5081) is gated on existingSubagent === undefined, so it is skipped.
  • If T3 never saw the original launch, nothing ever creates the child thread. The subagent's childThreadId points at a thread that doesn't exist.

The persisted rows match the recovery path: neither resumed subagent has modelSelection, which the recovery registration omits. Their startedAt values equal the timestamps of the two SendMessage tool calls in the resuming run.

A possible fix: when a recovered subagent reopens, create its child thread if it is missing. This should be create-only. The normal app_thread.created path turns into thread.metadata-updated when the thread exists, and that would overwrite an existing child thread's title and model with the parent's selection in the usual restart case.

Related but distinct: #16261, where the child thread exists but stops receiving items after a resume. Here the thread is never created at all.

Impact

Major degradation or frequent failure

Version or commit

Desktop 0.0.46-nightly.20261011.2955 (server host); iOS 2.0.0 (114) client. Source references at main ac2cc78.

Environment

macOS desktop app as the host, iOS app connected to it. Claude Code 2.1.296, claude-opus-5-5 parent and subagents.

Logs or stack traces

# orchestration_v2_projection_subagents for the parent thread (child_exists = row in projection_threads)
task               status       run          child_exists
...                completed    ordinal:1    1   (x4)
...                completed    ordinal:2    1   (x6)
a3c7388aabe4c4108  completed    ordinal:13   1
...                interrupted  ordinal:16   1   (x5)
a8e0071d9d9b60582  running      ordinal:21   0   <- resumed via SendMessage
ae3f3ef0894e84172  running      ordinal:21   0   <- resumed via SendMessage

# Timeline (UTC)
10:24:08  last turn item T3 stored for parent run 19 (parent CLI hit ENOSPC at 10:24:08)
17:30:46  parent CLI launches Agent a8e0071d9d9b60582 (toolu_014N...), not recorded by T3
17:30:50  parent CLI launches Agent ae3f3ef0894e84172, not recorded by T3
17:48:44  run 19 interrupted
17:57:45  run 21: SendMessage -> a8e0071d9d9b60582; subagent startedAt 17:57:46.016
17:57:48  run 21: SendMessage -> ae3f3ef0894e84172; subagent startedAt 17:57:48.406

Workaround

Read the subagent transcript from ~/.claude/projects/<project>/<session>/subagents/agent-<id>.jsonl.

Activity

  1. juliusmarminge commented on Oct 11, 2026

    @juliusmarminge
    Member

    Note

    Grok responding on behalf of Julius.

    Confirmed on main (bed9239). When SendMessage resumes a task the session doesn't know, recoverResumedClaudeSubagent (ClaudeAdapterV2.ts ~L4369) registers it with childThread: null, which assumes the child thread was created at launch. The later reopen goes through updateClaudeSubagentNode with existingSubagent defined, and app_thread.created (~L5074) only fires when existingSubagent === undefined. So if T3 never saw the original Agent launch, nothing creates the child thread, and the subagent's childThreadId points to a thread that doesn't exist.

    ENOSPC is an unusual way to trigger this. The recovery path itself still assumes the thread exists without checking. Your suggested fix is the right shape: on recovery, create the child thread only if it's missing, and leave existing threads alone so a normal restart doesn't overwrite their title or model.

    This is separate from #16261, where the thread exists but stays empty, and from #17596, which covers looking up the launch on instances with their own home directory.

  2. added
    bugSomething is broken or behaving incorrectly.
    acceptedfeature request accepted
    via-triageFiled through npx t3 triage
    on Oct 11, 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