Stop hook exit-0 output not reliably surfaced in hookAdditionalContext

Open 💬 0 comments Opened Jun 24, 2026 by patrickadamsprofessional

Summary

When a Stop hook exits 0 (approve) with JSON output on stdout, the output is not reliably surfaced to Claude in the subsequent turn's hookAdditionalContext. The hook runs and exits correctly, but Claude does not see the verdict.

Setup

A Stop hook (~/.claude/hooks/assertion-checker.sh) runs an adversarial review of every assistant response via the Anthropic API. It always prints a JSON verdict on stdout regardless of the outcome:

  • Approve/skip paths — exits 0, prints {"decision": "approve", "reason": "ADVERSARIAL CHECK PASSED: ..."}
  • Block path — exits 2, prints {"decision": "block", "reason": "⚠ ..."}

The CLAUDE.md for the project instructs Claude to begin every response with the hook verdict sourced from hookAdditionalContext.

Observed behavior

  • Block verdicts (exit 2) work correctly — the response is blocked as expected.
  • Approve/skip verdicts (exit 0) do not surfacehookAdditionalContext appears empty or absent in Claude's context on the following turn, even though the hook ran and produced stdout output.

Because Claude never sees the approve verdict in context, it cannot confirm the hook ran and must write "not yet run" each turn — defeating the purpose of the hook.

Expected behavior

Stdout output from a Stop hook that exits 0 should appear in hookAdditionalContext on the next turn, consistently — not just sometimes or not at all.

Reproduction

  1. Add a Stop hook that always prints {"decision": "approve", "reason": "check ran"} and exits 0.
  2. Instruct Claude (via CLAUDE.md) to begin every response with the content of hookAdditionalContext.
  3. Observe that Claude does not see the hook output in context and cannot surface it.

Impact

Makes it impossible to build visibility tooling on top of Stop hooks — any hook whose verdict should be visible to Claude on the next turn only works when it blocks (exit 2). Approve-path output is silently dropped.

View original on GitHub ↗