PreToolUse hook with matcher: "Agent" does not fire on parent Agent tool dispatch

Resolved 💬 3 comments Opened May 4, 2026 by alfredwesterveld Closed May 8, 2026
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

  1. 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 ...
``

  1. Register in .claude/settings.json:

``json
"PreToolUse": [
{ "matcher": "Agent",
"hooks": [{ "type": "command", "command": "/path/to/script.sh" }] }
]
``

  1. Reset sentinel: : > /tmp/agent-hook-fired.log
  2. From the main session, spawn a subagent:

Agent(subagent_type="Explore", prompt="...")

  1. Inspect /tmp/agent-hook-fired.log0 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.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗