Hook Exit Codes And JSON Output
Definition
How a shell hook communicates back to Claude Code: via its process exit code (success / block / error) and, on success, structured JSON on stdout that can allow, deny, or rewrite an action.
Key points
- Exit 0 = success: stdout parsed as JSON. For most events stdout goes to the debug log only; exceptions
UserPromptSubmit,UserPromptExpansion,SessionStartfeed stdout to Claude as context. - Exit 2 = blocking: stdout/JSON ignored, stderr is fed to Claude. Effect per event: PreToolUse blocks the call; UserPromptSubmit rejects the prompt; PermissionRequest denies; Stop prevents stopping; WorktreeCreate non-zero fails creation.
- Other exit (non-0/non-2) = non-blocking error: transcript shows
<hook> hook error+ first stderr line; execution continues. - JSON fields (universal):
continue(default true; Pythoncontinue_),stopReason,suppressOutput,systemMessage(shown to user, not model),terminalSequence. Decision: top-leveldecision: "block"+reason. hookSpecificOutput(requireshookEventName): PreToolUse →permissionDecision(allow/deny/ask/defer),permissionDecisionReason,updatedInput(needs allow/ask),additionalContext; PostToolUse →updatedToolOutput,additionalContext; SessionStart →additionalContext,initialUserMessage,sessionTitle,watchPaths,reloadSkills; PermissionRequest →decision:{behavior,updatedInput}; PermissionDenied →retry:true.- Multi-hook priority:
deny>defer>ask>allow— any singledenyblocks. - Async:
{async:true, asyncTimeout:30000}(Pythonasync_);asyncRewake:truewakes Claude on exit 2.
Why it matters for the exam
- D3 (20% of scored content) leans hard on the exit 0 / exit 2 / other semantics and where stdout vs stderr goes — a common multiple-choice discriminator.
PreToolUsereturningdeny(or exit 2) is the reliable enforcement answer — see PreToolUse hook enforcement.
Common gotchas
- On exit 2, JSON on stdout is ignored — only stderr reaches Claude.
updatedInputmust live insidehookSpecificOutputalongsidepermissionDecision: "allow"(orask), not at the top level.- Multi-hook resolution is deny-wins (
deny > defer > ask > allow), mirroring deny-beats-allow.
See also
Sources
Referenced by
Practice questions optional · AI
Generate fresh practice questions about this concept with AI. These are not vault-verified.