Repository navigation
[Bug]: Delegated-task notifications cancel queued Claude tool calls and tell the agent the user refused #15351
Description
Activity
Note
Grok responding on behalf of Julius.
Triage
Thanks for the detailed report and the repro script, @UzEE! The code path you describe is still on current
main(5e35272fda), and the two files you cited haven't changed since65731f986b. This looks like a real Claude bug. It's separate from open #15173, where the parent session is idle-released while it waits on a child. It's also separate from #12541, a PR about Claude steering that was closed without merging.What happens
An async
delegate_taskusescompletionWake: "always"(inOrchestratorMcpService). When that child finishes,ProviderContinuationServicesends a server-created agent message (createdBy: "agent",creationSource: "server",dispatchMode: "queue_after_active") with thedelegatedCompletionWakeDetailtext.dispatchMessagethen upgrades that delivery tosteer_activewhen every task in the batch usescompletionWake: "always"and the live session reportssupportsActiveSteering, which Claude does. The comment on that block says this delivery should never interrupt or restart a turn. Wait-mode children (settled_only) stay queued, so they don't hit this path.ClaudeAdapterV2.steerTurndoesn't check who sent the message, so every steer goes to the SDK as a user message withpriority: "now". After a steer, the adapter drops a result whoseterminal_reasonisaborted_toolsoraborted_streaming(isClaudeActiveSteeringAbortResult) and keeps the same T3 turn open for the model's next reply.That lines up with the hang you saw. Claude cancels the tool call that hadn't started yet, with "The user doesn't want to take this action right now. STOP…". T3 reads the
aborted_toolsresult as steering, not an interrupt, so the model's "I've paused, as you asked" lands on the turn that's still running. Nothing is queued behind it, so an autonomous thread waits forever. The Claude Code 2.1.286 changelog entry aboutnowmessages backgrounding a running call doesn't seem to cover calls that haven't started, which matches what you saw on 2.1.288.Likely fix area
- One option is to send only this server-created delegated-completion delivery with
priority: "next", which matches thenextcolumn in your script. User steers would keeppriority: "now". Runtime-question answers arecreatedBy: "user", so they'd stay on the current path too. - Another option is to stop upgrading async delegated completions to
steer_activefor Claude, and queue them after the active turn instead.
Either way, the goal is that tool calls the model has already issued still run, and the model isn't told the user refused them. I didn't re-run the live script. A maintainer will decide on the fix direction.
- One option is to send only this server-created delegated-completion delivery with
- addedbugSomething is broken or behaving incorrectly.Something is broken or behaving incorrectly.via-triageFiled through npx t3 triageFiled through npx t3 triage
on Oct 3, 2026
Before submitting
Area
apps/server
Steps to reproduce
In T3 Code:
delegate_taskchild withmode: "async".The script below reproduces it without T3. It sends the same message
ClaudeAdapterV2.steerTurnsends, partway through that kind of tool batch. Run it withnow, then withnext.repro.mjs
Expected behavior
The notification reaches the agent and every tool call still runs. The orchestrator promises this in the comment above its
steer_activerouting inapps/server/src/orchestration-v2/Orchestrator.ts: "Never interrupt/restart a turn for a notification."Actual behavior
The queued call never runs. Its tool result is:
The agent takes that as an instruction from the user. In two real threads it replied "I've paused, as you asked" and waited for a user who never came. For an autonomous thread that's the end of it, because nobody is around to send the next message.
A milder version hits MCP tools that are already running, such as
t3_thread_wait. Those fail with "The tool call was interrupted before a result was received". Agents usually retry that one.Script results on Claude Code 2.1.288:
prioritynowaborted_tools, then a new turn started for the notificationnextIn two more
nowruns the second call was read-only, so Claude Code ran it in parallel with the first and nothing was cancelled. Those turns still ended withaborted_tools.Cause:
steer_activewhen the session reportssupportsActiveSteering. The Claude adapter reportstrue.ClaudeAdapterV2.steerTurnsends every steer withpriority: "now". Onnow, Claude Code ends the current turn and cancels calls that haven't started.I think the fix is to send notification steers with
priority: "next". Claude Code delivers those at the next tool boundary without ending the turn, which is what thenextruns above show. User steers should keep"now", because #12541 explains why users want their own steers to land right away. I can open a PR once this is triaged.Impact
Major degradation or frequent failure
Version or commit
Observed on the desktop app, 0.0.46-nightly.20261003.2632 on Linux. Code read against main @ 65731f9.
Environment
Linux on WSL2, Claude Code 2.1.288, @anthropic-ai/claude-agent-sdk 0.3.276, claude-opus-5-5, full-access runtime mode.
Logs or stack traces
Timeline from one affected thread, in UTC:
A second thread showed the same sequence: the notification arrived at 02:07:16.9 and the queued Read was cancelled at 02:07:19.2.
Workaround
Tell agents in their prompt that this tool result means the call was cancelled and that they should retry it.
Related: #12541 covers Claude steer timing, and #15173 covers a Claude parent waiting on a
delegate_taskchild.Investigated with Opus 5.5 in Claude Code, running inside T3 Code.