[BUG] Sub-agent permission-denial user text is never propagated to the parent session
Environment
- Claude Code 2.1.172 (CLI), macOS (darwin 25.5)
- Reproduced with
general-purposesub-agents dispatched via the Agent tool
Summary
When a sub-agent's tool call triggers a permission prompt and the user denies it with a typed message, the user's verbatim text is delivered only to the sub-agent — it lands in the sub-agent's transcript as the rejected call's tool_result:
Permission for this tool use was denied. The tool use was rejected (...). The user said:
<the user's message>
The parent/orchestrator session never receives that text through any channel. It only ever sees whatever the sub-agent chooses to summarize in its final return. Direct, typed user input — the highest-priority signal in the system — is silently scoped to a child context and subject to a game of telephone.
Steps to reproduce
- Have the main agent dispatch a sub-agent (Agent tool) that performs Edits.
- When one of the sub-agent's permission prompts appears, deny it and type substantive feedback (e.g. "don't add a new field — use the existing one").
- Let the sub-agent return.
- Inspect the parent transcript (
~/.claude/projects/<proj>/<session-uuid>.jsonl): the user's text appears nowhere. It exists only in<session-uuid>/subagents/agent-<id>.jsonl.
Real-world consequence (observed)
In a long orchestrated session, the user gave a design correction at a sub-agent's permission prompt ("why is X a new field? isn't that what the existing field is for?"). The chain that followed:
- The sub-agent paraphrased the design objection into a trivial naming question in its final return — the only representation the parent ever saw.
- The parent resolved the naming question unilaterally ("naming pre-decided, so there's nothing to pause on") and re-dispatched a second sub-agent with the objected-to design hard-coded in the prompt ("Do NOT redesign, do NOT pause to ask about naming").
- The second sub-agent reproduced the change; the user denied again ("I already mentioned X should map to the existing field") — which again only the sub-agent saw.
- The user ultimately had to state the same correction a third time in the main session, having concluded the assistant was ignoring them. The parent never once saw their actual words.
Expected behavior
The verbatim denial message should also be surfaced to the parent session — e.g. injected as a system reminder on the parent's next turn:
While agent <id> was running, the user denied one of its tool calls with the message: "<text>"
At minimum, it should be obtainable via a hook. Today neither exists: PermissionDenied fires for auto-classifier denials and its output is ignored per the docs, and no Subagent* hook carries the denial text (#5812 requests a general parent/sub-agent bridge).
Related
- #5812 — feature request for hooks bridging sub-agent and parent context (would enable a workaround; doesn't exist today).
- #4593 / #5936 — the inverse routing asymmetry (Esc feedback intended for a sub-agent goes to the main agent). Together these show user-feedback routing around sub-agents is lossy in both directions.
- Adjacent artifact (happy to split into its own issue): a sub-agent killed mid-run via Esc is recorded in the parent transcript identically to a dispatch rejected before it started (
toolUseResult: "User rejected tool use"+ the standard rejection text). In the same session this led the parent to assert "there's no agent running right now… it never ran" about an agent whose on-disk transcript showed a 57-minute, 277-entry run — the user had to correct it from their own memory.