claude-code - 💡(How to fix) Fix [BUG] PreToolUse hooks: exit code 2 (block) shows misleading "error" prefix — add a clean "info" block mode [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#48015Fetched 2026-04-15 06:35:47
View on GitHub
Comments
0
Participants
1
Timeline
4
Reactions
0
Participants
Timeline (top)
labeled ×3unlabeled ×1

Error Message

The Error: PreToolUse:Bash hook error: prefix is misleading because:

  1. There is no error — the hook intentionally blocked the command to run a pre-flight check (in our case, an accessibility scan before git add/commit/push)
  2. Users see "Error" and think something is broken │ 2 │ Block │ Error: PreToolUse:Bash hook error: [<full command>]: <stderr> │ Provide a way for hooks to block a command with a clean informational message, not an error. For example:
  • A new exit code (e.g., exit 3) that means "block with info" and displays stderr without the error prefix
  • Or a configuration option in settings.json to set displayMode: "info" | "error" per hook Error: PreToolUse:Bash hook error: error condition. The "error" prefix confuses developers into thinking the hook itself is broken.

Error Messages/Logs

Error: PreToolUse:Bash hook error: [bash "$CLAUDE_PROJECT_DIR"/.claude/hooks/test-hook.sh]: Running pre-stage scan before git add... The Error: PreToolUse:Bash hook error: [bash "$CLAUDE_PROJECT_DIR"/.claude/hooks/test-hook.sh]: prefix should not appear when the hook intentionally blocks a command (exit 2) for informational purposes. The hook is working as designed — it is not an error condition.

Root Cause

The Error: PreToolUse:Bash hook error: prefix is misleading because:

  1. There is no error — the hook intentionally blocked the command to run a pre-flight check (in our case, an accessibility scan before git add/commit/push)
  2. Users see "Error" and think something is broken
  3. The long hook command path adds noise and confusion
  4. There's no way to suppress or customize this prefix from the hook script
RAW_BUFFERClick to expand / collapse

Preflight Checklist

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

What's Wrong?

Component: Hooks / PreToolUse

Severity: Low (UX/cosmetic)

Description:

When a PreToolUse hook exits with code 2 to block a command, Claude Code wraps the stderr output in this format:

The Error: PreToolUse:Bash hook error: prefix is misleading because:

  1. There is no error — the hook intentionally blocked the command to run a pre-flight check (in our case, an accessibility scan before git add/commit/push)
  2. Users see "Error" and think something is broken
  3. The long hook command path adds noise and confusion
  4. There's no way to suppress or customize this prefix from the hook script

Current behavior:

┌───────────┬─────────┬───────────────────────────────────────────────────────────────┐ │ Exit code │ Meaning │ Display │ ├───────────┼─────────┼───────────────────────────────────────────────────────────────┤ │ 0 │ Allow │ No message shown │ ├───────────┼─────────┼───────────────────────────────────────────────────────────────┤ │ 2 │ Block │ Error: PreToolUse:Bash hook error: [<full command>]: <stderr> │ └───────────┴─────────┴───────────────────────────────────────────────────────────────┘

What Should Happen?

Expected / requested behavior:

Provide a way for hooks to block a command with a clean informational message, not an error. For example:

  • A new exit code (e.g., exit 3) that means "block with info" and displays stderr without the error prefix
  • Or a way to set the display format via a header line in stderr (e.g., @@hook-info: <message>)
  • Or a configuration option in settings.json to set displayMode: "info" | "error" per hook

Example desired output: 🔍♿ a11y scan triggered · scanning 1 component(s) before git add ...

Instead of: Error: PreToolUse:Bash hook error:

Use case:

We built a pre-commit skill that hooks into git add, git commit, and git push via a PreToolUse hook. The hook intentionally blocks the git command, based on logic of skill. error condition. The "error" prefix confuses developers into thinking the hook itself is broken.

Environment:

  • Claude Code CLI
  • macOS / Darwin 25.4.0
  • Hook type: PreToolUse → Bash matcher

Error Messages/Logs

Steps to Reproduce

  1. Create a PreToolUse hook in .claude/settings.json:

{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
{
"type": "command",
"command": "bash "$CLAUDE_PROJECT_DIR"/.claude/hooks/test-hook.sh"
}
]
}
]
}
}

  1. Create the hook script at .claude/hooks/test-hook.sh:

#!/usr/bin/env bash set -euo pipefail

COMMAND="$(echo "$INPUT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('tool_input',{}).get('command',''))" 2>/dev/null || echo "")"

Block any git add command with an informational message

if echo "$COMMAND" | grep -qE '\bgit\s+add(\s|$)'; then
echo "Running pre-stage scan before git add..." >&2
exit 2
fi

exit 0

  1. Make the script executable:
    chmod +x .claude/hooks/test-hook.sh

  2. In Claude Code, ask the assistant to run:
    git add some-file.txt

Actual result:
Error: PreToolUse:Bash hook error: [bash "$CLAUDE_PROJECT_DIR"/.claude/hooks/test-hook.sh]: Running pre-stage scan before git add...

Expected result:
Running pre-stage scan before git add...

The Error: PreToolUse:Bash hook error: [bash "$CLAUDE_PROJECT_DIR"/.claude/hooks/test-hook.sh]: prefix should not appear when the hook intentionally blocks a command (exit 2) for informational purposes. The hook is working as designed — it is not an error condition.

Claude Model

None

Is this a regression?

Yes, this worked in a previous version

Last Working Version

No response

Claude Code Version

2.1.104

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

No response

extent analysis

TL;DR

To fix the issue, consider introducing a new exit code or a configuration option to display informational messages from hooks without the "Error" prefix.

Guidance

  • Investigate the possibility of adding a new exit code (e.g., exit 3) that indicates "block with info" and displays stderr without the error prefix.
  • Explore adding a configuration option in settings.json to set displayMode: "info" | "error" per hook, allowing for more control over the output.
  • Consider modifying the hook script to output a specific header line in stderr (e.g., @@hook-info: <message>) to indicate an informational message.
  • Review the documentation for Claude Code to see if there are any existing options or workarounds for customizing hook output.

Example

# In the hook script, output a header line to indicate an informational message
echo "@@hook-info: Running pre-stage scan before git add..." >&2
exit 2

Notes

The issue seems to be related to the way Claude Code handles hook output, and a solution may require changes to the Claude Code implementation or documentation. The suggested approaches are based on the information provided and may need to be adapted or refined based on further investigation.

Recommendation

Apply a workaround by modifying the hook script to output a custom message, as shown in the example above, until a more permanent solution is available. This approach allows for some control over the output without requiring changes to Claude Code.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix [BUG] PreToolUse hooks: exit code 2 (block) shows misleading "error" prefix — add a clean "info" block mode [1 participants]