PreToolUse hook reports error but doesn't block Bash tool execution

Resolved 💬 3 comments Opened Feb 5, 2026 by ghost Closed Feb 8, 2026

PreToolUse hook reports error but doesn't block Bash tool execution

Description

PreToolUse hooks for the Bash tool report errors but don't actually prevent the tool from executing. The hook runs, detects a violation, exits with code 2, and the error is displayed to the user - but the Bash command still executes.

Steps to Reproduce

  1. Configure a PreToolUse hook for Bash in ~/.claude/settings.json:
{
  "PreToolUse": [
    {
      "matcher": "Bash",
      "hooks": [
        {
          "type": "command",
          "command": "if echo \"$INPUT\" | jq -e '.tool_input.command | test(\"git push\")' > /dev/null; then echo '❌ BLOCKED: git push commands are forbidden.' >&2; exit 2; fi"
        }
      ]
    }
  ]
}
  1. Run a Bash tool with git push
  2. Observe: "PreToolUse:Bash hook error" is displayed
  3. Bug: The git push command still executes successfully

Expected Behavior

When a PreToolUse hook exits with a non-zero code (especially exit 2), the tool execution should be blocked/cancelled.

Actual Behavior

The hook error is reported but the Bash command executes anyway:

⏺ Bash(git push)
  ⎿  PreToolUse:Bash hook error
  ⎿  To https://github.com/...
        abc123..def456  main -> main

Impact

PreToolUse hooks cannot actually prevent dangerous operations like:

  • Pushing to remote repositories without review
  • Running destructive commands
  • Bypassing safety checks

Environment

  • Claude Code CLI
  • Hook type: PreToolUse with Bash matcher
  • Hook exit code: 2

View original on GitHub ↗

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