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_status returns available: false, tabId: null with nothing to say the caller is not live. It is easy to read as a browser fault.
Diagnosis
actsAsCaller, writes and writesThreads all go through assertLiveCaller (apps/server/src/mcp/threadAccess.ts), which needs a non-null activeRunId. 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
- The parent launches a native subagent that does not finish within the turn (Claude:
run_in_background: true; Codex: spawn and don't wait), then ends its turn. The run goes tocompleted. - The subagent calls
preview_openwith{"open": false, "reuseExistingTab": false}. It is refused. - In the same window
preview_status,t3_preview_listandt3_thread_listsucceed. - Control: with the parent turn held open, the same call succeeds (Claude: 47 preview calls with no failures; Codex: open and close succeeded).
Version
A fork pinned at upstream 29980a3140; the gate files are identical on main at 243c9994d0. 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
| 1 | # Codex, 2026-10-11 UTC |
| 2 | 17:33:36.514 parent run completed (activeRunId: null) |
| 3 | 17:35:45 subagent preview_open -> "The calling provider no longer owns an active thread run." |
| 4 | |
| 5 | # Claude, server trace for the refused call |
| 6 | 16:48:40.747 McpServer tools/call tool=preview_open 2.9ms |
| 7 | 16:48:40.748 mcp.loadCaller 1.1ms |
| 8 | (no PreviewToolkit.invoke span: refused before reaching the browser) |
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_status could report it too.
Prepared with Claude Opus 5.5 and approved by Jackson.