UserPromptSubmit hooks: stdout causes error despite docs saying it's added to context
Bug Description
UserPromptSubmit hooks cannot output anything to stdout without causing a "UserPromptSubmit hook error". This contradicts the documentation which states that stdout from UserPromptSubmit hooks is "added as context".
Environment
- Claude Code version: 2.0.69
- OS: macOS Darwin 25.1.0
- Shell: bash
Steps to Reproduce
- Create a minimal UserPromptSubmit hook that outputs to stdout:
#!/bin/bash
# test-hook.sh
echo "test output"
exit 0
- Register it in
.claude/settings.json:
{
"hooks": {
"UserPromptSubmit": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "bash test-hook.sh"
}
]
}
]
}
}
- Start Claude Code and type any prompt
Expected Behavior
According to the hooks documentation:
For SessionStart and UserPromptSubmit hooks, stdout is added as context
The output "test output" should be added as context to Claude, not cause an error.
Actual Behavior
Any stdout from UserPromptSubmit hooks causes:
UserPromptSubmit hook error
This was verified through systematic testing:
| Test | Result |
|------|--------|
| echo '{"decision":"continue"}' + exit 0 | ERROR |
| printf "test" + exit 0 | ERROR |
| cat <<< "test" + exit 0 | ERROR |
| No output + exit 0 | ✅ Works |
| No output + exit 2 | ✅ Works (blocks as expected) |
Workaround
Log to files instead of stdout:
#!/bin/bash
{
echo "=== $(date -Iseconds) ==="
echo "Detected: something"
} >> "$HOME/.claude/my-hook.log"
exit 0
Impact
This prevents useful patterns like:
- Adding dynamic context based on prompt analysis
- Injecting relevant information before Claude processes the prompt
- Implementing prompt-aware context enrichment
Additional Context
- Other hook types (SessionStart, PreToolUse, PostToolUse) handle stdout correctly
- SessionStart stdout IS visible in hook feedback
- PreToolUse stdout IS processed for decision JSON
- Only UserPromptSubmit appears to have this issue
Documentation Reference
The discrepancy appears to be between:
- Documented behavior: "stdout is added as context"
- Actual behavior: "stdout causes error"
Either the documentation needs updating or this is a bug in the hook handler.
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗