[UX] Stop hook displays 'error' for intentional blocking behavior

Resolved 💬 6 comments Opened Nov 29, 2025 by severity1 Closed Feb 28, 2026

Summary

When a Stop hook intentionally blocks Claude to provide guidance (exit 0 with "decision": "block"), the displayed message shows "Stop hook error:" even though no error occurred - the hook is working exactly as designed.

Current Behavior

Ran 1 stop hook
  ⎿  Stop hook error: Files were modified this turn. Use the Task tool to spawn 'memory-updater' agent...

The word "error" implies something went wrong, but this is the intended behavior - the hook successfully blocked Claude's stop and provided guidance for what to do next.

Expected Behavior

The message should not say "error" when the hook:

  • Exits with code 0 (success)
  • Returns valid JSON with "decision": "block" and a "reason"

Suggested alternatives:

  • "Stop hook:" (neutral)
  • "Stop hook message:" (informational)
  • "Stop hook blocked:" (accurate - describes what happened)

Reserve "Stop hook error:" for actual errors (exit code 2, invalid JSON, etc.).

Hook Implementation

# Exit 0 (implicit), returns valid JSON
output = {
    "decision": "block",
    "reason": "Files were modified this turn. Use the Task tool to spawn..."
}
print(json.dumps(output))

This follows the documented pattern for Stop hooks that intentionally block Claude to request follow-up actions.

Impact

  • Users see "error" and think something is broken
  • Developers may waste time debugging hooks that are working correctly
  • Creates confusion about whether hooks are functioning as intended

Related Issues

  • #10986 - Clarify blocking vs non-blocking hook status in hook messages
  • #10463 - "Stop hook error" displayed despite hooks producing zero output

Environment

  • Claude Code Version: 2.0.55
  • Platform: Linux (WSL2)

View original on GitHub ↗

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