Skip to content

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

Description

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    duplicateThis issue or pull request already exists

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions