PreToolUse hook 'if' field does not filter hook process spawning (v2.1.87)
Resolved 💬 3 comments Opened Mar 31, 2026 by r-akitani-quando Closed Mar 31, 2026
Bug Description
The if field on PreToolUse hooks does not prevent the hook process from spawning. According to the documentation, if should filter at the hook level before the process is started, but in practice the hook script runs for every Bash command regardless of the if condition.
Steps to Reproduce
- Add the following to
.claude/settings.local.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"if": "Bash(git commit *)",
"command": ".claude/hooks/pre-commit-ci.sh"
}
]
}
]
}
}
- Run any Bash command (e.g.
npx prettier --write file.ts)
Expected Behavior
The hook script should NOT be spawned for npx prettier since it doesn't match Bash(git commit *).
Actual Behavior
The hook script IS spawned for every Bash command, including npx prettier, echo, npm run format, etc. The if field is completely ignored.
Workaround
Reading tool_input.command from stdin JSON inside the hook script and filtering manually:
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // ""')
if ! echo "$COMMAND" | grep -q "git commit"; then
exit 0
fi
Environment
- Claude Code version: 2.1.87
- OS: macOS (Darwin 24.5.0)
- Session was restarted after changing settings
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗