PreToolUse/PostToolUse hooks do not fire for subagent (Agent tool) tool calls
Bug Report
Claude Code version: 2.1.76
Platform: Linux (Fedora/Bazzite, kernel 6.17.7)
Shell: bash
Summary
When the main session spawns subagents via the Agent tool, any Bash, Edit, Write, Read, or Grep tool calls made by the subagent do not trigger PreToolUse or PostToolUse hooks configured in ~/.claude/settings.json. Only tool calls made directly by the main session thread fire the hooks.
This means any compliance, auditing, or safety hooks that depend on intercepting tool calls are silently bypassed when work is delegated to subagents — which is the recommended pattern for parallelized workflows.
Reproduction Steps
- Configure a
PostToolUsehook in~/.claude/settings.json:
``json``
{
"hooks": {
"PostToolUse": [{
"matcher": "Bash",
"hooks": [{
"type": "command",
"command": "/path/to/protocol-tracker.sh",
"timeout": 5
}]
}]
}
}
- The hook script increments a counter in a JSON file whenever a
git commitcommand is detected in Bash tool calls.
- In a session, run
git commitdirectly from the main thread — the hook fires and the counter increments. This works correctly.
- In the same session, spawn an Agent that runs
git commitinside its Bash calls — the hook does not fire. The counter stays at zero.
- At end of session, the state file shows
{"commits": 0}despite multiple commits having been made by subagents.
Expected Behavior
PreToolUse and PostToolUse hooks should fire for all tool calls within a session, regardless of whether the call originates from the main session or a subagent spawned by the Agent tool. The hook's stdin JSON should include an agent_id or source field to distinguish which agent made the call.
Actual Behavior
Hooks only fire for main-session tool calls. Subagent tool calls bypass all configured hooks entirely. There is no warning or indication that hooks are being skipped.
Impact
This is a compliance and safety gap for any workflow that uses hooks for:
- Audit trail tracking (counting commits, ticket creation, deployments)
- Security gates (blocking dangerous commands, checking for secrets in edits)
- Protocol enforcement (ensuring business gates are checked before mutations)
In our case, we use hooks for gate enforcement (PreToolUse:Bash) and protocol compliance tracking (PostToolUse:Bash). Both are silently bypassed when we parallelize work via the Agent tool, which is the primary recommended workflow for performance.
Workaround
We query the actual systems of record (git log, Jira API) at checkpoint time rather than trusting hook-maintained counters, and reconcile the state file afterward. This makes the state file eventually consistent but loses the real-time warning capability.
Related Issues
- #26923 — PreToolUse hook exit code 2 does not block Task tool calls
- #5812 — Feature: Allow hooks to bridge context between subagents and parent
- #16126 — Feature: Add agent identity to PreToolUse hook data
- #14859 — Feature: Agent hierarchy in hook events
- #22665 — Subagent does not inherit permission allowlist from settings.json
Suggested Fix
- Subagents should inherit and execute parent session hooks — same hooks, same matchers, same enforcement
- Hook stdin JSON should include agent context —
agent_id,parent_agent_id,agent_namefields so hooks can distinguish source - Documentation should note this limitation if inheritance is intentionally excluded
This issue has 7 comments on GitHub. Read the full discussion on GitHub ↗