[FEATURE] Interrupt blocking TaskOutput when the main agent receives a SendMessage
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
In multi-agent workflows, a subagent may send a message to the main agent using SendMessage, continue working on another task, and wait for a response from the main agent.
However, if the main agent is currently blocked inside a call such as:
TaskOutput(task_id="<task-id>", block=true, ...)
the incoming SendMessage is not processed until the TaskOutput call completes or times out.
This can create a circular wait:
- A subagent sends a question or intermediate result to the main agent.
- The subagent continues other work and then waits for the main agent's response.
- The main agent is blocked waiting for another task through
TaskOutput. - The main agent cannot process the subagent's message while
TaskOutputis blocking. - Neither agent can make progress without a timeout or manual interruption.
A blocking task wait should not prevent the main agent from receiving agent-coordination messages. Otherwise, TaskOutput can deadlock workflows that rely on SendMessage for synchronization and clarification.
Proposed Solution
Make blocking TaskOutput calls interruptible when a SendMessage addressed to the calling agent arrives.
When the main agent is waiting in TaskOutput(block=true) and an incoming message is received, Claude Code should:
- Interrupt the blocking
TaskOutputwait immediately.
- Preserve the background task without cancelling or modifying it.
- Return a structured interruption result from
TaskOutput, for example:
``json``
{
"status": "interrupted",
"reason": "incoming_message"
}
- Deliver the pending
SendMessageto the main agent so it can process and respond to it.
- Allow the main agent to call
TaskOutputagain afterward if it still needs to wait for the original task.
The important behavior is that an incoming coordination message takes priority over a passive blocking wait.
This should apply only to blocking calls. TaskOutput(block=false) behavior would remain unchanged.
If TaskOutput is being deprecated in favor of another waiting mechanism, the same interruptibility requirement should apply to its replacement: blocking waits must yield when agent-to-agent messages arrive.
Alternative Solutions
Use short TaskOutput timeouts
The main agent can repeatedly call TaskOutput with short timeouts. This reduces the maximum delay but introduces polling latency, additional tool calls, token usage, and race conditions.
It also requires the model to select an appropriate timeout without knowing when a message will arrive.
Poll with TaskOutput(block=false)
The main agent can avoid blocking and poll task status manually. This is inefficient and makes orchestration prompts considerably more complex.
Require subagents to write results to files
Subagents can communicate through shared files instead of SendMessage. This works for one-way result delivery but does not support interactive questions, clarifications, approvals, or iterative coordination.
Queue messages until TaskOutput completes
This appears to be the current effective behavior. It is not sufficient because the task being awaited may depend indirectly on the message being processed, resulting in a deadlock.
Priority
Critical - Blocking my work
Feature Category
Developer tools/SDK
Use Case Example
Example scenario:
- The main agent starts two subagents, Agent A and Agent B.
- The main agent calls
TaskOutput(block=true)to wait for Agent A.
- Agent B discovers an ambiguity and calls:
``text``
SendMessage(
to="main",
message="Should I modify the existing implementation or replace it?"
)
- Agent B performs unrelated work and then pauses because it needs the main agent's decision.
- Agent A cannot complete because its work depends on an artifact that Agent B will produce after receiving that decision.
- The main agent remains blocked in
TaskOutputand does not process Agent B's message.
- The workflow remains stalled until the
TaskOutputtimeout expires or the user manually interrupts it.
With the proposed behavior:
- Agent B's
SendMessagearrives. - The blocking
TaskOutputcall is interrupted. - The main agent reads and answers Agent B's question.
- Agent B resumes and produces the required artifact.
- Agent A completes.
- The main agent can call
TaskOutputagain and collect Agent A's result.
This allows message-driven agent coordination without relying on timeout-based polling.
Additional Context
Related issues were found, but none request this specific behavior:
- #77950 reports nested agents stalling when messages fail to reach their direct parent.
- #75043 reports nested-agent completion notifications being delivered to the wrong agent and parent agents stalling.
- #74113 reports background agents going idle without reliably delivering their final
SendMessage. - #77908 reports that named agents cannot be addressed through
TaskOutputorTaskStop.
Those issues concern routing, delivery reliability, or task addressing. This request concerns the scheduling behavior of a valid incoming SendMessage while the recipient is blocked inside TaskOutput.
Conceptually, TaskOutput(block=true) should wait on either of two events:
background task completes
OR
an incoming agent message arrives
The first event should resume the caller.