Repository navigation
delegate_task from a background native Claude subagent fails with parent_not_active after the parent's turn settles #16808
Description
What happened
On a Claude thread (claudeAgent, claude-opus-5-5, full-access), the agent launched native subagents with Claude Code's built-in Agent tool (run_in_background: true) and ended its turn. Later, a subagent called the inherited mcp__t3-code__delegate_task tool to start a Codex review. The call failed with:
parent_not_active: Delegated tasks require an active run owned by this MCP provider session.
This happened 10 times on one thread between 2026-10-04 and 2026-10-07:
- 8 calls came from background native subagents. One of those subagents had been launched by another native subagent.
- 2 calls came from the parent itself. Both were on turns that Claude started on its own after a subagent sent it a message (
Another Claude session sent a message: <agent-message from="…">).
Every successful delegate_task on the same thread ran during a turn that T3 started, from a user message or t3_thread_send.
T3 lists the native subagents as thread:provider:claudeAgent:native-thread:… with status idle and latestRunId: null. The T3 orchestration instructions tell agents to prefer native subagent tools for same-provider work when they support the chosen model, so this situation comes up in ordinary use.
Diagnosis
Line references are for b37fcea.
- The T3 MCP credential is scoped to a thread and provider instance, not to a run (McpSessionRegistry.ts#L130-L142). Claude receives it as the
t3-codeMCP server (ClaudeAdapterV2.ts#L937-L945). Native subagents inherit the parent's MCP servers, so their calls are checked against the parent thread's runs. delegateTaskrequires the newest run to bepreparing,starting,runningorwaiting, with a root node and a matching provider instance (OrchestratorMcpService.ts#L1356-L1371, ThreadManagementService.ts#L326-L333).- When the root Claude turn ends, the run is stored as
waiting(RunExecutionService.ts#L633-L644). Within seconds, checkpoint capture marks itcompleted(CheckpointCaptureService.ts#L201-L216). Native background subagents that are still running do not keep it open. - This matches the intended projection. In the
claude_background_subagent_after_rootfixture, the background subagent's frames are buffered after the root settles and drained into a continuation run that starts when the subagent completes (input.ts#L17-L19). Until then, the subagent keeps executing tools, including the inherited T3 MCP tools, while the thread has no active run.
Each step behaves as designed, but together they mean a background native subagent cannot call delegate_task once its parent's turn has ended. The error message suggests a lost or stale session, which hides the real cause.
Parent-side variant. The two parent failures happened on turns that Claude started after receiving a subagent's <agent-message>. In this build, such a wake opens its continuation run only at the result frame when no task notification is buffered (ClaudeAdapterV2.ts#L5043-L5057). The parent's tool calls in that turn therefore ran without an active run. T3 later attached them to a continuation run created 25–32 s after the failed call. #15055 (merged 2026-10-03, after this preview build) starts the continuation on system/init. The provider log shows system/init about 100 ms after such a message, so this variant is probably fixed on main. I have not verified that on a newer build.
On main (cd41c4a), the delegateTask guard (OrchestratorMcpService.ts#L1791-L1805), checkpoint completion and the fixture are unchanged. The subagent case should still apply there.
Possible directions, for the maintainers to choose:
- keep the parent run
waitingwhile native background subagents launched by that run are live; - or, if this is intended, return a distinct error such as "native background subagents cannot delegate after the parent turn has ended", and say so in the orchestration instructions.
Steps to reproduce
These steps follow from the source and the production failures below. I did not rerun them as a clean repro, because this machine has since disabled Claude's native Agent tool.
- On a Claude thread with T3 MCP orchestration, send:
Use the Agent tool with run_in_background: true to launch one general-purpose subagent with this prompt: "Run sleep 90 with Bash, then call mcp__t3-code__delegate_task with task 'Reply with exactly OK.' and target provider codex, and reply with the raw tool result." Then reply ROOT_STARTED and stop. - The root turn ends, and the run goes
waiting→completed. - About 90 s later, the subagent's
delegate_taskreturnsparent_not_active. - For comparison, the same
delegate_taskcall made by the parent during a user-started turn succeeds.
Version
0.0.46-preview.20261002.2598 (b37fcea). 9 of the 10 failures happened on the unmodified official binary. The last one happened on a server rebuilt from the same SHA with an unrelated SQLite scheduling patch (see #14701).
Environment
Linux x64 (LXC, kernel 7.0), T3 running as a systemd user service, Claude Code 2.1.292 through the Agent SDK. Parent provider claudeAgent (claude-opus-5-5), delegation target codex.
Evidence
# UTC. R<n> = run ordinal on the affected thread; every run is claudeAgent with a root node.
# Sources: orchestration_events (statev2.sqlite) and the Claude session transcripts.
# Background native subagent, 2026-10-04
03:01:56.870 R59 running (user turn); parent launches Agent(run_in_background=true)
03:06:16.099 R59 waiting
03:06:17.022 R59 completed # no active run from here on
03:56:28.150 subagent: delegate_task -> parent_not_active
03:59:18.121 R60 created
# Parent turn started by a subagent's agent-message, 2026-10-05
17:31:49.726 R298 completed
17:36:56.447 transcript: isMeta user "Another Claude session sent a message: <agent-message from=…>"
17:37:18–17:37:51 parent runs four tool calls with no T3 run
17:38:22.690 parent: delegate_task -> parent_not_active
17:38:47.825 R299 created (creationSource=provider, text "Background task completed."); the
earlier tool calls are stored under R299 with processing-time timestamps
17:39:09.643 R299 completed
# Comparison on the same thread, T3-started turns
2026-10-05 17:48:36 parent, R300 running (user turn) -> delegate_task OK
2026-10-07 10:42:44 parent, R414 running -> delegate_task OK
# All 10 failures: the latest run was `completed` (never `waiting`). All 419 runs on the
# thread stayed on claudeAgent. At each failure the provider session was attached and
# `ready`, with no stop since that attachment.Related issues
#16565 has the same error with a different trigger: a provider switch-and-back that leaves the credential on the wrong provider. This thread never switched provider. #15173: idle session release revokes the MCP credential, which surfaces as HTTP 401 invalid_mcp_credential rather than this tool-level error, and the session was attached at every failure. #15055 probably fixes the parent-side variant.
Fix applied or workaround
No change to T3. Agents worked around it by relaying the delegation through the parent on the next T3-started turn. This machine now denies Claude's native Agent tool (permissions.deny: ["Agent"]) and uses delegate_task only.
Filed by
Claude Code (Claude Opus 5.5), with investigation by Codex (GPT-6.1-Sol) sub-agents, following the t3 triage playbook.
Activity
Jacksondr5 commentedon Oct 11, 2026
This now affects every writing tool, not only
delegate_task, and it reproduces on Codex as well as Claude.What happened
A native subagent that outlives its parent's turn has every writing MCP tool refused with "The calling provider no longer owns an active thread run." Read-only tools keep answering, so
preview_statusreturnsavailable: false, tabId: nullwith nothing to say the caller is not live. It is easy to read as a browser fault.Diagnosis
actsAsCaller,writesandwritesThreadsall go throughassertLiveCaller(apps/server/src/mcp/threadAccess.ts), which needs a non-nullactiveRunId. The gate's comment says it stops "a provider token that outlived its session". Here the session is alive and working; it is the run that has ended. I exercised only the preview tools; device, worktree handoff, pull request and thread tools share the gate by declaration.Steps to reproduce
run_in_background: true; Codex: spawn and don't wait), then ends its turn. The run goes tocompleted.preview_openwith{"open": false, "reuseExistingTab": false}. It is refused.preview_status,t3_preview_listandt3_thread_listsucceed.Version
A fork pinned at upstream
29980a3140; the gate files are identical onmainat243c9994d0. Not reproduced on an upstream build.Environment
Ubuntu 24.04.5, Node 24.14.0, Claude Code 2.1.296 (Opus 5.5), codex-cli 0.162.1 (GPT-6-Astra).
Evidence
Related issues
#17809 and #17885 hit the same message in the parent's wake turn. #16565 is the same message from a different arm of the gate (provider switch).
Workaround
Keep the parent turn open until the subagent returns.
Both directions listed above would fix this. Whichever is chosen, the error could say that the parent turn ended while background work continues, and
preview_statuscould report it too.Prepared with Claude Opus 5.5 and approved by Jackson.