[BUG] PostToolUse hook stdout/stderr never surfaces in agent context
Describe the bug
PostToolUse hook stdout and stderr are never injected into the agent's context window. The hook fires (confirmed via file side-effects), the script runs, but echo output is silently dropped. This makes PostToolUse hooks useless for injecting reminders, guardrails, or context at the moment a tool completes.
To reproduce
- Add a PostToolUse hook in
.claude/settings.json:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "echo 'CANARY_STRING'"
}
]
}
]
}
}
- Run any Bash command (e.g.
echo "ping") - The hook fires (verified by replacing
echowithtouch /tmp/test-file— file appears) - But
CANARY_STRINGnever appears in the tool result or anywhere the agent can see it
Observed behavior
Tested all combinations:
| Hook type | Exit code | stdout visible? | stderr visible? |
|-------------|-----------|-----------------|-----------------|
| PreToolUse | 0 | No | No |
| PreToolUse | non-zero | No | Yes (as block error) |
| PostToolUse | 0 | No | No |
| PostToolUse | non-zero | No | No |
Only blocking PreToolUse hooks (exit non-zero) surface their stderr to the agent via the error message format: PreToolUse:Bash hook error: [command]: <stderr>.
Expected behavior
PostToolUse hook stdout should be appended to the tool result (or injected as a system message), so the agent can see and act on it. This is the primary use case for PostToolUse hooks — injecting context-sensitive guidance at the moment a specific tool completes.
Workaround
Use a PreToolUse blocking hook (exit 2) that writes to stderr. The agent sees the error, processes the message, and retries the command. Requires a breadcrumb file so it only blocks once per session. Ugly but functional.
Environment
- Claude Code CLI + Conductor (Mac app)
- macOS
- Tested mid-session and with fresh sessions
- Hooks hot-reload mid-session (not a stale-config issue)
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗