Description
A PreToolUse hook matching Bash, configured in ~/.claude/settings.json, is not invoked when a Bash tool call originates from a subagent dispatched via the Agent tool (observed specifically with the built-in Explore agent type). The same hook correctly fires and denies matching commands when run directly in the main thread.
Repro
~/.claude/settings.json has:
"hooks": {
"PreToolUse": [
{ "matcher": "Bash", "hooks": [{ "type": "command", "command": "~/.claude/hooks/pre-bash.sh" }] }
]
}
pre-bash.sh hard-denies cd <path> && <cmd> compound commands (regex-matched), returning:
{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"..."}}
Verified via direct pipe-test that the hook correctly denies the exact leaked command:
echo '{"tool_input":{"command":"cd /path && git log --oneline --all"},"cwd":"/some/dir"}' | ~/.claude/hooks/pre-bash.sh
# => correctly returns permissionDecision: deny
However, when an Explore subagent (launched via the Agent tool) issues the identical compound command shape (cd /path && git log ...), it is NOT denied by the hook. Instead it surfaces as a normal interactive permission prompt ("This command changes directory before running git, which can execute untrusted hooks from the target directory. Approve only if you trust it."), as if the hook were never invoked for that tool call.
Expected
PreToolUse hooks configured globally should apply uniformly to all Bash tool calls, regardless of whether they originate from the main agent loop or a subagent spawned via the Agent tool.
Actual
Subagent-issued Bash calls bypass the hook entirely, falling through to the default interactive permission prompt instead of being hard-denied per the hook's logic.
Impact
Permission-prompt-reduction hooks (blocking known-bad command shapes, enforcing org conventions, etc.) cannot be relied upon when work is delegated to subagents, which undermines a common workflow pattern (dispatching Explore/general-purpose agents for research/search tasks).
Description
A
PreToolUsehook matchingBash, configured in~/.claude/settings.json, is not invoked when a Bash tool call originates from a subagent dispatched via the Agent tool (observed specifically with the built-inExploreagent type). The same hook correctly fires and denies matching commands when run directly in the main thread.Repro
~/.claude/settings.jsonhas:pre-bash.shhard-deniescd <path> && <cmd>compound commands (regex-matched), returning:{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"..."}}Verified via direct pipe-test that the hook correctly denies the exact leaked command:
However, when an
Exploresubagent (launched via theAgenttool) issues the identical compound command shape (cd /path && git log ...), it is NOT denied by the hook. Instead it surfaces as a normal interactive permission prompt ("This command changes directory before running git, which can execute untrusted hooks from the target directory. Approve only if you trust it."), as if the hook were never invoked for that tool call.Expected
PreToolUsehooks configured globally should apply uniformly to all Bash tool calls, regardless of whether they originate from the main agent loop or a subagent spawned via the Agent tool.Actual
Subagent-issued Bash calls bypass the hook entirely, falling through to the default interactive permission prompt instead of being hard-denied per the hook's logic.
Impact
Permission-prompt-reduction hooks (blocking known-bad command shapes, enforcing org conventions, etc.) cannot be relied upon when work is delegated to subagents, which undermines a common workflow pattern (dispatching Explore/general-purpose agents for research/search tasks).