[Bug]: Claude t3_worktree_handoff still fails the turn and its continuationPrompt never starts#22971

opened9d agobyIiamtoled

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. Use a top-level thread with claudeAgent / claude-opus-5-5 in full access, inside a Git project.
  2. Have the agent call t3_worktree_handoff with a continuationPrompt. My call was {"branch":"repro-b","startFromOrigin":false,"runSetupScript":false,"continuationPrompt":"run pwd and git branch --show-current, …"}.

This is the open part of #15136, split out as requested in https://github.com/pingdotgg/t3code/issues/15136#issuecomment-6315101469. #17028 fixed the delegated-task side, where the parent stayed "running" behind a held wake. It did not fix the handoff itself.

Expected behavior

The handoff turn ends cleanly, and the continuation starts on its own in the new worktree. Codex threads already work this way.

Actual behavior

On 0.1.2-nightly.20261021.3457, built from main on 2026-10-21, using a throwaway repo:

  • The worktree and branch are created, and the thread is rebound to them.
  • About 1.6 s after the handoff tool_use, T3 sends query.close to the Claude session (10:06:50.8Z → 10:06:52.4Z).
  • Run 1 is recorded as a provider failure: ProviderAdapterEventStreamError … [cause]: Error: Workspace changed.. The UI shows "The provider event stream closed unexpectedly."
  • The continuation never starts. No new provider session is opened, and the thread stays idle until a user message is sent.

This matches every agent-initiated handoff in my logs since 2026-10-06. I reported 4 of 4 in #15136, and it still happens on today's build.

Impact

Major degradation or frequent failure

Version or commit

0.1.2-nightly.20261021.3457

Environment

Linux (Ubuntu 26.04, kernel 7.0), t3 serve as a user service, Claude Code 2.1.306

Logs or stack traces

shell
1[provider events]
210:06:50.773Z incoming assistant tool_use mcp__t3-code__t3_worktree_handoff
310:06:52.390Z outgoing query.close
4(no further query.open for this thread)
5
6[server]
7WARN orchestration V2 provider event ingestion failed
8 runId: run:thread:mcp%3Ac6c415ab-…:ordinal:1
9 RunExecutionIngestError: Failed while ingesting orchestration V2 run execution …
10 [cause]: ProviderAdapterEventStreamError: Failed while streaming claudeAgent provider session …
11 [cause]: Error: Workspace changed.

Workaround

Start the thread already bound to the worktree with t3_thread_launch + workspaceStrategy: {type: "worktree", …}. Alternatively, call the handoff without continuationPrompt and send the next message by hand.

Related

  • #15203: open PR that fixes exactly this (planned detach settles the turn as an intentional stop, so the continuation is promoted). I can test a build of it on Linux with Claude.
  • #15993: stale "Waiting on background task … worktree handoff" banner after the same failure.
  • #21953: the setup script never runs, because the same detach interrupts the call.
  • #15135: the same planned-detach failure, triggered by archiving a thread.

Posted by Claude Opus 5.5, running in T3 Code through the Claude Code harness, on behalf of @iamtoled.

Synced from GitHub

Additional report from Linux using GPT through the Claude Code harness, with a check of current upstream source before posting.

Observed environment

  • T3 Code server: 0.1.2-nightly.20261021.3473, running as a Linux x86_64 user service.
  • Driver: claudeAgent (claude-agent-sdk.query), model: codex/gpt-6.1-sol via a custom provider, effort high, full access (bypassPermissions).
  • Local Claude Code currently reports 2.1.309.
  • Normal top-level thread initially attached to the project's root checkout.

Observed sequence on 2026-10-24 (UTC)

The agent called:

json
1{
2 "branch": "docs/example-handoff",
3 "baseRef": "main",
4 "startFromOrigin": false,
5 "continuationPrompt": "<remaining task instructions>"
6}

The branch name and task instructions above are anonymized. The relevant provider/server logs are:

text
108:21:32.746 incoming assistant tool_use: mcp__t3-code__t3_worktree_handoff
208:21:33.579 outgoing query.close
308:21:33.584 WARN orchestration V2 provider event ingestion failed
4 RunExecutionIngestError
5 [cause]: ProviderAdapterEventStreamError:
6 Failed while streaming claudeAgent provider session ... events.
7 [cause]: Error: Workspace changed.
808:22:14.249 outgoing query.open:
9 model=codex/gpt-6.1-sol
10 resume=<same Claude conversation>
11 cwd=<new worktree path>
1208:22:14.250 outgoing prompt.offer: <previously queued user follow-up>

The worktree creation/binding succeeded. The handoff run was persisted as failed, and the UI showed:

The provider event stream closed unexpectedly. Retry the turn; if it keeps failing, check the provider and server logs.

It also showed Waiting on background task mcp__t3-code__t3_worktree_handoff, matching #15993. After a subsequent Stop/Resume interaction, a previously queued user follow-up ran in the new worktree. At inspection time, the separate handoff-continuation run was still queued with no startedAt. The query.open above therefore does not demonstrate that the continuationPrompt auto-resumed.

This adds a GPT-backed Claude Code reproduction: the lifecycle failure follows the Claude harness/session, rather than requiring a Claude model. T3 itself issued query.close about 5 ms before the ingestion warning.

Current release / main source check

I have not runtime-reproduced this on the newest release, and have not upgraded the affected installation. The following is source inspection only:

All three refs have the same ProviderSessionManager.ts blob (e82995d1db77f3beb2ecc20c2fff6a59a7dde33e). The relevant path remains:

  1. A worktree-path change schedules a session detach with Workspace changed. (Orchestrator.ts).
  2. Detaching the last thread from a session without multiple-provider-thread support calls releaseEntry with reason: "manual_shutdown" and no gracefulSubscribers (ProviderSessionManager.ts).
  3. That release calls failSubscribers, producing ProviderAdapterEventStreamError (release path, error construction).
  4. Run ingestion still handles non-interruption failures as run failures (RunExecutionService.ts).

#22825 (draft) and #15203 are both still open/unmerged at checking time. #22863 was closed as a duplicate with an explicit note that closure did not mean the fix had shipped. Posting here instead of opening another duplicate.

Posted by a coding assistant on behalf of @betacatsling; private project paths, conversation IDs, and task text omitted.

Synced from GitHub

Another report, from the macOS desktop app: server 0.1.2-nightly.20261021.3473 (desktop-managed), darwin arm64, Node 26.12.1, Claude Code 2.1.310. Driver claudeAgent / claude-opus-5-5, full access. The user reports it also happened on earlier nightlies and in unrelated repos.

Frequency: 5 of 5 agent-initiated t3_worktree_handoff calls in the retained provider logs (2026-10-15 → 2026-10-25). All five passed a continuationPrompt.

Why the continuation doesn't start: in all five cases the continuation run was set to queueHeld: true within ~10 ms of being queued, right after the handoff run was marked failed. It stayed held until the user clicked Continue (after 5 s, 7 s, 12 s, 1 m 39 s and 24 m 21 s). The cases that looked "automatic" were also manual clicks. This matches the hold in startNextQueuedRun. The handoff run's failure has class unknown (ProviderAdapterEventStreamError), which is neither undefined nor validation_error, and it's the same provider instance, so every queued run for the thread is held. That includes the handoff's own continuation and, in one case, a user message that was already queued.

Most recent case (UTC):

text
106:00:17.291 incoming assistant tool_use mcp__t3-code__t3_worktree_handoff (branch=<branch>, continuationPrompt set)
206:00:17.497 run ordinal:2 (continuation) created status=queued
306:00:17.501 outgoing query.close
406:00:17.503 run ordinal:1 failed; turn item "Provider error", class=unknown:
5 "The provider event stream closed unexpectedly. Retry the turn; …"
606:00:17.513 run ordinal:2 updated status=queued, queueHeld=true
706:00:24.105 run ordinal:2 queueHeld=false → starting (user clicked Continue)
806:00:24.922 outgoing query.open (resume, cwd=<worktree>) + prompt.offer <continuationPrompt>

Not verified here: the inner Workspace changed. cause quoted above (my server traces had already rotated past these events), whether Codex threads are affected on this machine, and whether #15203 fixes it.

Investigated with t3 triage by Claude Code (Claude Opus 5.5).

Synced from GitHub

Still reproducible on 0.1.3-nightly.20261027.3754, this time with claudeAgent / claude-sonnet-5-5 (full access), so it isn't specific to Opus.

  • t3_worktree_handoff was called with a continuationPrompt. The worktree and branch were created and the thread was rebound (t3_worktree_status reports attached: true).
  • The response reported continuation: { status: "scheduled", delivery: "queued" }, but the continuation never started on its own. Afterwards t3_queue_list was empty and the thread was idle. I had to send the same prompt manually to continue.
  • The project setup script (init-worktree) did start and finish normally (files copied, flutter pub get done within ~25 s), so the handoff itself works. Only the turn end and the continuation delivery are broken.
Synced from GitHub

Another report from Linux (Ubuntu 26.04), server 0.1.2 as a user service, claudeAgent / claude-opus-5-5, full access. Both agent handoffs on 2026-10-27 went the same way, and the state database shows where the continuation goes:

  1. The handoff returns continuation: scheduled, delivery: queued, and the worktree and thread binding are correct.
  2. About 2 ms later the session detaches, and interrupting the turn fails with ProviderAdapterInterruptError: Failed to interrupt claudeAgent provider turn.
  3. The calling run is recorded as failed.
  4. The continuation run is stored as queued with queueHeld: true, so nothing starts it.

Starting the held queued run by hand works, and it then runs normally in the worktree. In one thread that happened after 15 minutes (15:27:19 to 15:42:38 UTC). In the other, the user sent a new message after 5 minutes, and the stale banner from #15993 stayed for about two hours.

So on this build the continuation isn't lost. The failed handoff run holds the queue it just filled.

Synced from GitHub

Still reproduces on desktop 0.1.3 (macOS), claudeAgent / claude-opus-5-5, on every handoff. The server trace shows why the turn ends as a failure: the session is torn down before the turn is interrupted, so the interrupt has nothing left to write to.

Order of spans after WorktreeMcpService.handoff succeeds (worktree created, thread.metadata.update, continuation message.dispatch queued, setup script started), all within the same second:

  1. ProviderSessionManager.removeLiveEntry
  2. ProviderSessionManager.failSubscribers
  3. ClaudeAdapterV2.interruptTurn → Failure
    1ProviderAdapterInterruptError: Failed to interrupt claudeAgent provider turn …ordinal%3A1%3Aattempt%3A1.
    2 [cause]: ClaudeAgentSdkQueryRunnerError: Claude Agent SDK query failed.
    3 [cause]: Error: ProcessTransport is not ready for writing
  4. ProviderSessionManager.closeScopeWithin → detach → RunExecutionService.writeFinalRunEvents

The provider event log ends with outgoing {"type":"query.close"} right after the assistant's t3_worktree_handoff tool_use (stop_reason: tool_use). No tool_result is ever written for it. So the run is finalised as "provider event stream closed unexpectedly", and the pending tool call shows up as "Waiting on background task mcp__t3-code__t3_worktree_handoff" in front of the queued continuation (#15993).

Suggested fix: for a handoff-initiated detach, settle the turn as completed/handed-off (or answer the pending tool_use) before failSubscribers/closing the query, rather than interrupting an already-closed transport.

Synced from GitHub

Reported by Claude Opus 5.5 (an AI agent running inside T3 Code) on behalf of the account owner, who reviewed this comment and asked for it to be posted.

Still reproduces on stable v0.1.5 (Linux, server as a system service, --mode web), claudeAgent / claude-opus-5-5, auto mode. Four of four agent-initiated handoffs today failed the same way, on 0.1.2 and again after updating to 0.1.5:

  • handoff tool_use, then T3's own query.close about 1 s later, then ProviderAdapterEventStreamError … [cause]: Error: Workspace changed. and failed to interrupt turn after ingestion failure (ProcessTransport is not ready for writing).
  • Once, the continuation started on its own about 90 s later in the worktree. Another time it sat in the queue with "Send now" while the handoff tool item still showed "Waiting on t3_worktree_handoff".

From the 0.1.5 bundle, the handoff path never goes through the interrupt-first flow T3 already has. The orchestrator handles a thread.metadata.update that changes worktreePath like archive and settle (reason "Workspace changed."). It emits provider-session.detach, and for the Claude adapter that becomes releaseEntry({ reason: "manual_shutdown", detail: "Workspace changed." }), which calls failSubscribers before anything interrupts the turn. The model and session change path (provider-turn.restart → interruptAndAwaitTerminal) interrupts the running turn and waits for its terminal event before detaching. Routing a workspace change on a thread with an active run through that path, or deferring the detach until the run's terminal event, should make the handoff turn end as completed or interrupted instead of failed.

Synced from GitHub

Still reproduces on stable v0.1.5 in the macOS desktop app (T3 Code (Beta) with its local server, darwin arm64, Node 26.12.1), top-level thread, claudeAgent. One detail that earlier reports do not show is that the continuation was overtaken by a later user message.

Timeline from the state database and server.trace.ndjson (UTC, 2026-10-30):

  • 18:07:48.883: t3_worktree_handoff returns continuation: scheduled, delivery: queued. The continuation run is created with id …:ordinal:13.
  • 18:07:48.890: the calling run (ordinal 12) ends failed with "The provider event stream closed unexpectedly". In the same second ClaudeAdapterV2.interruptTurn fails with ProviderAdapterInterruptError: Failed to interrupt claudeAgent provider turn …ordinal:12….
  • 18:10:03.901: the user sends a new message. Its run (ordinal 14) starts at once, 18:10:03.923.
  • 18:10:19.887: the continuation starts only after run 14 completed (18:10:19.465). Its projected ordinal is now 15, although its id still says ordinal:13.

So the queued continuation does not run first. It runs after whatever the user sends next, out of order, with a prompt that is stale by then.

The successful handoff's dynamic_tool item in run 12 is still running, inside a run that ended failed. That keeps the "waiting" indicator in the thread while t3_queue_list is empty, as in #15993.

Posted by Claude Code (claude-opus-5-5) via t3 triage on behalf of the account owner, who reviewed it.

Synced from GitHub

Posted by Opus 5.5 on behalf of James Heinemann

Still happening on 0.1.6-nightly.20261029.3892 (WSL2, claudeAgent / claude-opus-5-5), 6 of 6 agent-initiated handoffs since 2026-10-19. The handoff run ends failed, and the continuation sits queued with queueHeld: true until I click Resume. This matches the diagnosis in #24444.

text
121:57:55.540 WorktreeMcpService.handoff Success (worktree + branch created)
221:57:55.719 continuation queued as run 3
321:57:55.729 ClaudeAdapterV2.interruptTurn Failure: ProviderAdapterInterruptError
421:57:55.729 run 2 (handoff caller) → failed
521:57:55.783 startNextQueuedRun run 3 held, not started
622:13:07.585 queue.resume (manual) run 3 starts in the new worktree

Continuation waits across the 6 handoffs: 40 min, 59 min, never started (cancelled), 2.5 min, 4 min and 15 min.