Stop hook trace `No stderr output` fires every turn for passing hooks (session-scoped)
Claude Code bug: "Stop hook feedback: No stderr output" trace fires on every turn (session-scoped)
Summary
In a single long-running session, the Stop hook trace [<command>]: No stderr output started displaying after every assistant turn — for ~30+ consecutive turns — despite the hook passing cleanly (exit 0, no stderr, no block). The same hook configuration in other sessions does not produce this trace. Once the noise starts in a session, it persists.
Environment
- Platform: Windows 11 Home (10.0.26200), PowerShell + Bash via Git Bash
- Project: octopus (real-estate pipeline)
- Model: claude-opus-4-7 (1M context)
- Session duration: ~3 hours
- Background tasks during session: yes — 2 long-running Bash background jobs (~85 min combined runtime for an Airtable mutation batch and a recovery script)
Hook config (.claude/settings.json)
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "uv run --script .claude/hooks/quality_gates.py 2>/dev/null"
}
]
}
]
The hook (.claude/hooks/quality_gates.py) imports claude_agent_sdk.StopHookInput, runs just typecheck on changed .py files and just find_dupes_win on changed source files, returns {"decision": "block", "reason": "..."} only on gate failure, otherwise exits 0 silently. Confirmed with direct invocation:
$ '{"cwd":"...","stop_hook_active":false}' | uv run --script .claude/hooks/quality_gates.py
$ echo "exit: $LASTEXITCODE"
exit: 0
Exit code 0, no stdout, no stderr.
What I see every assistant turn
Stop hook feedback:
[uv run --script .claude/hooks/quality_gates.py 2>/dev/null]: No stderr output
This appears as a system-level message at every turn end, regardless of what the hook actually returned. The hook is not blocking and not writing to stderr (the 2>/dev/null redirect would catch it anyway).
Expected behavior
Stop hook traces should only display when:
- The hook returns a block decision, OR
- The hook writes something useful to stderr, OR
- Some verbose/debug flag is enabled
A passing hook that exits 0 with empty output should not produce visible feedback every turn.
Smell test — likely culprit
The rewakeSummary field in the settings schema is documented as:
@internalOne-line summary shown to the user in the terminal when anasyncRewakehook exits with code 2. Defaults to"Stop hook feedback".
The hook here is not asyncRewake and does not exit 2 — but the harness is still rendering this trace with the "Stop hook feedback" summary string. So either:
- A regression made the trace fire on non-asyncRewake Stop hooks
- Some session-state transition (long background task completion? Bash hook PreToolUse error chain?) flipped the harness into a mode where every Stop hook trace is rendered
Session-only repro
The same hook config in fresh sessions of the same project does not show this trace. Something about long-session state (possibly background-task completion notifications interleaving with Stop hooks) seems to switch the harness's hook-trace rendering on. Once on, it stays on for the rest of the session.
What I tried in-session
- Tightened the dedupe gate file filter to skip non-source files (no effect on trace)
- Made the hook exit silently on pass with no stdout (no effect on trace)
- Confirmed direct hook invocation works cleanly (exit 0, empty stderr)
- Note:
2>/dev/nullin the command was already there before; removing it would just let stderr pass through, but stderr is empty anyway
Related observation
The PreToolUse:Bash hook (check_cd_command.py) shows a similar artifact: PreToolUse:Bash hook error: [...]: No stderr output appears on every Bash invocation, but the hook is also passing cleanly (otherwise the Bash call would be blocked). Both hooks share the same 2>/dev/null redirect pattern in their commands.
Asks
- Is the "Stop hook feedback" trace supposed to render for non-asyncRewake hooks that pass silently?
- What session-state condition flips the harness into rendering every hook trace? (So we can avoid triggering it.)
- Is there a settings flag to suppress hook traces when there's no block / no useful output?
<signature>🦀 sent by Claude Code</signature>
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗