[BUG] Hook error messages shown on every tool call even when hooks exit 0

Resolved 💬 12 comments Opened Mar 16, 2026 by noether-current Closed May 16, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

All three hook types (PreToolUse, PostToolUse, UserPromptSubmit) display "hook error" messages in the transcript on every tool call, even when the hook scripts exit 0 for non-matching commands. The hooks function correctly — they format files, validate commits, and block bad inputs — but Claude Code reports them as errors anyway.

The message is just "PreToolUse:Bash hook error" with no further detail. It appears twice per Bash call (once per registered hook) and once per Edit call.

What Should Happen?

Hooks that exit 0 should be silent. "hook error" should only appear for non-zero, non-2 exit codes (per the documentation). Exit 0 = allow, exit 2 = block.

Error Messages/Logs

● Bash(git status -u)
  ⎿  PreToolUse:Bash hook error
  ⎿  PreToolUse:Bash hook error
  ⎿  On branch feat/playground-design-sandbox
     Your branch is up to date with 'origin/feat/playground-design-sandbox'.
     ...

● Update(~/Work/projects/workout/.claude/hooks/session-audit.sh)
  ⎿  Removed 1 line
  ⎿  PostToolUse:Edit hook error

❯ Did you check the files...
  ⎿  UserPromptSubmit hook error

Steps to Reproduce

  1. Create .claude/settings.json with hook configuration:

``json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{ "type": "command", "command": "bash .claude/hooks/validate-commit.sh" }
]
}
]
}
}
``

  1. Create .claude/hooks/validate-commit.sh:

``bash
#!/usr/bin/env bash
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')
echo "$COMMAND" | grep -qE '^git commit' || exit 0
if ! echo "$COMMAND" | grep -qP '#\d+'; then
echo "Commit message must include issue reference (#NN)." >&2
exit 2
fi
exit 0
``

  1. Run any Bash command via Claude Code (e.g., ask it to run git status)
  2. Observe "PreToolUse:Bash hook error" in transcript even though the hook exits 0

Note: The hook correctly blocks git commit without #NN (exit 2) and allows all other commands (exit 0). Manual testing confirms exit 0:

echo '{"tool_input":{"command":"git status"}}' | bash .claude/hooks/validate-commit.sh; echo $?
# outputs: 0

Claude Model

Opus

Is this a regression?

I don't know

Claude Code Version

2.1.76 (Claude Code)

Platform

Anthropic API

Operating System

Other Linux

Terminal/Shell

WSL (Windows Subsystem for Linux)

Additional Information

  • The error appears on every tool call, not just mismatched ones
  • Actions still proceed (hooks are non-blocking when they exit 0) — the error label is cosmetic but noisy
  • All hooks follow the same pattern: early exit 0 for non-matching commands, exit 2 to block
  • jq is installed and functional (tested), though jq --version prints just jq- (no version number) — possibly relevant
  • Removing set -euo pipefail from hooks did not fix the issue
  • Adding explicit exit 0 at end of all scripts did not fix the issue

View original on GitHub ↗

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