[BUG] Hook stderr output is silently swallowed — not visible to user (all hook types)
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?
Bug
Hook stderr output is never displayed to the user in the terminal, despite the hooks documentation stating that stderr should be visible to the user. This affects all hook types, not just SessionStart.
- stdout → delivered to Claude as context (works correctly)
- stderr → silently discarded (bug)
This means there is no mechanism for hooks to communicate anything directly to the user.
Result
- Claude receives the stdout lines in its context
- User sees nothing in the terminal from any stderr method
- Tested across both SessionStart and Stop hook types
- Tested with bash
>&2,tee /dev/stderr, Node.jsprocess.stderr.write(), andconsole.error() - Tested with
claude,claude --resume, and multiple session restarts - None reach the user's terminal
Prior issues
This was reported in #10808 and #25543 (both closed without resolution — stale/duplicate). The underlying problem remains: there is no working mechanism for hooks to display messages to the user.
Suggested fix
Either:
- Fix the bug: pipe hook stderr to the user's terminal (as documented)
- Add
displayMessageto the hook output schema — a field that Claude Code renders directly in the terminal after the hook completes
Option 1 is the minimal fix and matches existing documentation. Option 2 (from #10808) would be a richer solution.
Environment
- Claude Code CLI (latest as of 2026-03-12)
- macOS (Darwin 25.3.0)
- Tested in zsh terminal, with
claudeandclaude --resume
What Should Happen?
Expected
stderr from hooks should be displayed to the user in the terminal, as documented.
Impact
- Users cannot get confirmation that setup hooks ran successfully
- No way to surface warnings (e.g., missing
.env, failed health checks) to the user - Hook authors following the documented
>&2pattern get no output - Affects all hook types — SessionStart, Stop, and likely PreToolUse/PostToolUse as well
Error Messages/Logs
Steps to Reproduce
Reproduction
Setup
.claude/settings.json:
{
"hooks": {
"SessionStart": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "bash .claude/hooks/test.sh"
}
]
}
],
"Stop": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "node .claude/hooks/test-stop.js"
}
]
}
]
}
}
1. Bash hook (SessionStart) writing to stderr
.claude/hooks/test.sh:
#!/usr/bin/env bash
echo "stdout: visible to Claude"
echo "stderr: should be visible to user" >&2
2. Node.js hook (Stop) writing to stderr
.claude/hooks/test-stop.js:
#!/usr/bin/env node
process.stderr.write('[test] Direct stderr write\n');
console.error('[test] console.error message');
console.log('[test] stdout for Claude');
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.74
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
_No response_
This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗