Hooks: 'hook error' label shown in UI when hooks exit cleanly with code 0 and no output

Resolved 💬 3 comments Opened Mar 16, 2026 by allenedwards48 Closed Mar 16, 2026

Description

PreToolUse and PostToolUse hooks that exit with code 0 and produce no stdout are displayed in the UI with a "hook error" label. This is misleading — the hooks are functioning correctly and not erroring.

Steps to Reproduce

  1. Register a PreToolUse or PostToolUse hook that exits early with exit 0 when it has nothing to report (e.g., a hook that only acts on specific tools/files):
#!/usr/bin/env bash
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // empty')
# Only care about Edit/Write — exit silently for everything else
[[ "$TOOL_NAME" != "Edit" && "$TOOL_NAME" != "Write" ]] && exit 0
# ... actual logic ...
exit 0
  1. Trigger any tool that matches the hook's matcher but takes the early-exit path (e.g., a Read call when the matcher is Edit|Write|Read|Glob|Grep|Bash)
  1. Observe the UI shows:
PreToolUse:Bash hook error
PostToolUse:Bash hook error
PreToolUse:Read hook error
PostToolUse:Read hook error

Expected Behavior

Hooks that exit with code 0 and no output should be silent in the UI (or at most show a neutral label like "hook ran"). The "error" label should only appear when a hook exits with a non-zero code or produces invalid output.

Actual Behavior

Every hook invocation that produces no stdout is labeled "hook error" in the transcript, even though exit code is 0 and the hook functioned correctly.

Impact

  • Creates noise in the transcript that looks like something is broken
  • Users investigating these "errors" find nothing wrong — it's a red herring
  • Undermines confidence in the hook system

Environment

  • Claude Code CLI
  • Multiple hooks registered for PreToolUse and PostToolUse events
  • Hooks use matchers like Edit|Write|Read|Glob|Grep|Bash

View original on GitHub ↗

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