PreToolUse hook with matcher: "Agent" does not fire on parent Agent tool dispatch
Filed by Claude Code (claude-opus-4-7, 1M context) on behalf of the user.
What's Wrong?
A PreToolUse hook registered with matcher: "Agent" is never invoked when the main session dispatches the Agent tool to spawn a subagent. The hook script does not execute at all — not "fires but updatedInput ignored" (#39814) and not "fires but exit code ignored" (#40580). The script simply never runs.
What Should Happen?
PreToolUse hooks matching the Agent tool should be invoked before the subagent is dispatched, the same way PreToolUse:Bash hooks fire before Bash commands.
Repro
- Hook script with an unconditional sentinel write at the very top, before any matcher logic, before reading stdin:
``bash``
#!/usr/bin/env bash
set -euo pipefail
date -u '+%FT%TZ' >> /tmp/agent-hook-fired.log
input=$(cat)
# ... rest of hook ...
- Register in
.claude/settings.json:
``json``
"PreToolUse": [
{ "matcher": "Agent",
"hooks": [{ "type": "command", "command": "/path/to/script.sh" }] }
]
- Reset sentinel:
: > /tmp/agent-hook-fired.log - From the main session, spawn a subagent:
Agent(subagent_type="Explore", prompt="...")
- Inspect
/tmp/agent-hook-fired.log→ 0 bytes. Script never ran.
Manual invocation works:echo '{"tool_name":"Agent","tool_input":{"subagent_type":"Explore","prompt":"x"}}' | bash script.sh
→ writes sentinel, returns proper \updatedInput\ JSON, exit 0.
Variations Tested
- \
matcher: "Agent"\— does not fire - \
matcher: "Task"\(legacy tool name) — does not fire - Project-level settings (\
.claude/settings.json\) — does not fire - Same project's \
PreToolUse:Bash\hook fires reliably in the same session, so hook infrastructure itself is healthy.
Impact
Cannot enforce a model/prompt gate on subagent dispatch from the parent session. In our case: a hook that injects \model: "haiku"\ and a \CONFIDENCE:\ suffix for \Explore\ subagent calls, plus a TSV telemetry row per dispatch. None of it executes.
Environment
- macOS Darwin 25.2.0
- Claude Code, model: claude-opus-4-7 (1M context)
- Hook command paths use \
\$CLAUDE_PROJECT_DIR\, settings file mtime predates session start (config was loaded at SessionStart).
Related
- #39814 — \
updatedInput\ignored for Agent (hook fires; my hook does not fire) - #40580 — exit code ignored for subagent's own tool calls (subagent-internal; mine is parent-side)
- #44534 — deny not enforced for Agent (similar surface, different symptom)
---
This issue was drafted and filed by Claude Code (claude-opus-4-7, 1M context) at the user's request, after empirically reproducing the bug in their session.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗