PermissionRequest hooks are never dispatched for agent-teams teammates (works for in-process subagents on the same build, 2.1.220)
Summary
PermissionRequest hooks are never dispatched for a tool call made by an agent-teams teammate (an Agent spawn given a name, which runs the delegate as its own claude process), even though the identical hook-originated ask verdict does dispatch PermissionRequest correctly for an in-process/backgrounded subagent on the same build.
Consequence: a teammate blocked on an ask renders no dialog. The prompt appears only inside the teammate's own TUI pane, which in a delegation workflow nobody is watching. From the orchestrator's side the teammate is indistinguishable from one that has finished — it simply reports idle. In one observed case the prompt sat for ~2 minutes before being answered in that pane, so this is not a silent deny; the gating works, but the request becomes invisible to the human.
This is adjacent to but distinct from #79177 (in-process subagents; a commenter reports that case working on 2.1.220, which matches our own observation) and #82150 (no local dialog constructed for a backgrounded subagent while a hook holds the request). Here the event is never dispatched at all, and the spawn kind is different.
Environment
- claude-code 2.1.220, Linux x86_64, interactive TTY.
- Hooks registered at managed scope (
/etc/claude-code/managed-settings.json): aPreToolUsehook with matcherBash, aPermissionRequesthook, and a diagnostic hook registered on many events including both of the above (unconditional, no debug gate — it is the instrument used below). - The
PreToolUsehook returnshookSpecificOutput.permissionDecision: "ask"for git commit chains. That is the ask under test — it originates from a hook, not from a built-in permission flow.
Observed behaviour
Control: in-process fork — PermissionRequest fires correctly
Session 4e08817c…, agent_id a77c7af79f6497549, agent_type: "fork", tool_use_id toolu_01Fp41XMKNgpeS8SHgMijWpo:
01:07:16.308 PreToolUse tool_use_id toolu_01Fp41XM… → hook returns permissionDecision "ask"
01:07:16.801 PermissionRequest tool_use_id toolu_01Fp41XM… (same agent_id, same tool_input.command)
So a hook-originated ask reaches PermissionRequest on this build.
Failing case: agent-teams teammate — PermissionRequest never fires
Two teammates of the same team, each with a confirmed hook-originated ask from the same PreToolUse hook and the same commit-chain code path:
| teammate | session | PreToolUse events | PermissionRequest events |
| --- | --- | --- | --- |
| A | dd36abd2… | 113 | 0 |
| B | 97c4af2e… | 54 | 0 |
For teammate A, tool_use_id toolu_0118rFvGoLkKqmmyiAos18To: PreToolUse logged at 01:05:09.167, hook verdict ask. No PermissionRequest entry for that tool_use_id — and none anywhere in that session's log for its entire lifetime. The corresponding PostToolUse arrives at 01:07:12.292, ~2m3s later, showing the git commit executed successfully. So the ask was answered — in the teammate's own pane.
Note on identification: a teammate carries no agent_id (it is the main agent of its own session), so agent-id absence proves nothing. These sessions were identified instead by payloads carrying team_name.
Never dispatched, not dispatched-and-failed
The diagnostic hook is registered on PermissionRequest unconditionally and would have logged an entry if the event reached the hook chain at all. It logged zero for both teammate sessions. The only failure entries in those logs are ordinary command failures unrelated to permissions.
Expected
PermissionRequest should dispatch for a teammate's tool call as it does for an in-process subagent, so that a PermissionRequest hook can render the approval UI wherever the operator actually is.
Questions
- Is the absence of
PermissionRequestfor agent-teams teammates intentional, or an oversight in the same area as #79177? - Is there a supported way for a hook to observe or answer a teammate's pending permission request out-of-band, given the prompt is confined to that teammate's pane?
Happy to provide the timestamped per-session hook-event logs for all three cases above.
4 Comments
Bump
Update draft for #82418 (status as of claude-code 2.1.234)
Re-verified this on 2.1.234. The core defect stands, but the consequence section of the original report is no longer accurate and understates what the current build does — proposing this as an update comment (or edited body).
Still accurate
PermissionRequestis never dispatched for an agent-teams teammate's tool call — on either side. Re-confirmed live on 2.1.234 with an unconditionalPermissionRequestdiagnostic hook installed at user scope on both the lead and the teammate: a teammate's hook-originatedask(and equally a settingspermissions.askrule match) produced zeroPermissionRequestevents in the teammate session and zero in the lead session, across multiple rounds.permission_requestmessage and queues the approval dialog directly with a literalpermissionResult:{behavior:"ask"}— no hook dispatch, no permission-mode evaluation, no classifier on that path. There is structurally no seam where aPermissionRequesthook could fire or answer.No longer accurate (2.1.220-era observations, superseded)
Notificationhook event withnotification_type: "worker_permission_prompt"("<teammate> needs permission for Bash") when the ask forwards, followed by a regularpermission_promptnotification for the same prompt_id. That is a supported observation point for raising external surfaces.What remains broken / unanswered
PermissionRequestnot dispatching for teammates looks like the same oversight family as #79177 — the receive path predates the hook, and nothing on it dispatches hooks at all.worker_permission_promptNotification event, but answering it out-of-band remains unsupported — no hook on either side can resolve the forwarded request, sincePermissionRequest(the only resolving hook) never fires for it.This is very close to a problem I ran into while building an external orchestration layer around Claude Code.
I ended up treating permissions as a property of the individual team member rather than relying on the lead session to implicitly own the permission boundary.
Each member in my setup has an explicit permission/capability configuration, and the orchestrator knows which member is executing a tool call. That makes the approval path independent of whether the work is being done by the lead, a teammate, or a restarted session.
The interesting part of this issue to me is that the Agent Teams communication path and the hook/permission path seem to be two separate layers. The teammate request can now reach the lead UI, but there's still no
PermissionRequesthook seam for an external orchestrator to participate in the decision.I'm building this approach in Hackeroom:
Planner → Coder → Reviewer → Tester → Auditor
Each role runs as its own Claude Code session with its own model, permissions and skills.
[hacker room](
https://github.com/SinghAbhinav04/dev-house)
I wonder if a future Agent Teams API could expose a first-class permission event containing at least the teammate/session identity, tool call, requested capability, and a way to approve/deny it programmatically. That would make external orchestration and policy enforcement much cleaner than trying to infer permission state from notifications.
Reproduced on 2.1.233 (Linux, tmux). Setup: a
PreToolUsehook (matcherBash) returning apermissionDecision: "ask"for a marker command, plus an unconditionalPermissionRequestlogging hook, both at user scope.askdispatchedPermissionRequest(withagent_idpopulated) and rendered the approval dialog in the main session — matches your observation.PreToolUsewith theaskverdict applied and the teammate blocked waiting for approval — but noPermissionRequestevent was dispatched in either the teammate's session or the orchestrator's session for the entire wait.One difference from your 2.1.220 observation: on 2.1.233 the teammate's pane no longer shows a locally answerable prompt — it reports the permission request as forwarded to the team leader — yet in our run no approval dialog surfaced in the leader's UI either during a multi-minute observation window, so the pending request was effectively invisible from both ends while the teammate sat blocked.
So we can confirm the core report: a hook-originated
askfrom a teammate never reachesPermissionRequesthooks, which also rules out the workaround of using such a hook to surface the approval elsewhere. Flagging this to the team as a bug in how teammate permission requests are routed to the hook system.🤖 Generated with Claude Code