Hook Events Reference
Hook Events Reference
Claude Code provides 17 lifecycle events that hooks can attach to. Events are the trigger system — hooks attach to events and enforce rules.
All Events
| Category | Event | When it fires | Can block? | Supports matcher? |
|---|---|---|---|---|
| Session | <code>SessionStart</code> | Session begins, resumes, or clears | No | Yes (startup, resume, clear, compact) |
| Session | <code>SessionEnd</code> | Session terminates | No | Yes (clear, logout, prompt_input_exit, etc.) |
| Session | <code>PreCompact</code> | Before context compaction | No | Yes (manual, auto) |
| User | <code>UserPromptSubmit</code> | User submits a prompt (before processing) | Yes (decision: block) | No |
| User | <code>Stop</code> | Agent finishes responding | Yes (decision: block) | No |
| User | <code>Notification</code> | Claude Code sends a notification | No | Yes (notification type) |
| Tools | <code>PreToolUse</code> | Before a tool call executes | Yes (deny/allow/ask) | Yes (tool name regex) |
| Tools | <code>PostToolUse</code> | After a tool call succeeds | No (tool already ran) | Yes (tool name regex) |
| Tools | <code>PostToolUseFailure</code> | After a tool call fails | No (tool already failed) | Yes (tool name regex) |
| Tools | <code>PermissionRequest</code> | Permission dialog appears | Yes (allow/deny) | Yes (tool name regex) |
| Agents | <code>SubagentStart</code> | Subagent spawned | <strong>No</strong> — can only inject context | Yes (agent type name) |
| Agents | <code>SubagentStop</code> | Subagent finishes | Yes (decision: block prevents stopping) | Yes (agent type name) |
| Agents | <code>TeammateIdle</code> | Team teammate about to go idle | Yes (exit 2) | No |
| Agents | <code>TaskCompleted</code> | Task marked complete | Yes (exit 2) | No |
| Config | <code>ConfigChange</code> | Config file changes during session | Yes (decision: block) | Yes (config source) |
| Git | <code>WorktreeCreate</code> | Worktree being created | Yes (non-zero exit fails creation) | No |
| Git | <code>WorktreeRemove</code> | Worktree being removed | No | No |
SubagentStart / SubagentStop Detail
SubagentStart — Context Injection (NOT Blocking)
SubagentStart CANNOT block subagent creation. Exit code 2 only shows stderr to the user — it does not prevent the subagent from spawning. This is a critical distinction from PreToolUse.
What SubagentStart CAN do:
- Inject additionalContext: Return JSON with
hookSpecificOutput.additionalContext— this string is added to the subagent's context. - Side effects: Logging, notifications, etc.
- Matchers: Filter by agent type name (e.g.,
qa,dev,issue-creator,Explore,Plan).
SubagentStart input (on stdin as JSON):
Note: No
prompt field is available in SubagentStart input. Only agent_id and agent_type are provided beyond the common fields.SubagentStart output (inject context):
Settings.json example:
SubagentStop — CAN Block (Prevents Stopping)
SubagentStop CAN block via
decision: "block" — this prevents the subagent from stopping (it continues working). Uses the same decision control as Stop hooks.
Enforcement Asymmetry
This creates an enforcement asymmetry between the two spawn paths:
| Spawn path | Can block spawn? | Can inject context? | Can enforce tool use? |
|---|---|---|---|
| <strong>Manual (Agent tool)</strong> | Yes — PreToolUse deny | Yes — via prompt | Yes — PreToolUse hooks |
| <strong>Native delegation</strong> | <strong>No</strong> | Yes — additionalContext | Yes — frontmatter PreToolUse hooks |
To compensate: use SubagentStart to inject plan context and frontmatter PreToolUse hooks for defense-in-depth (e.g., QA agent blocks Write/Edit/Bash at the hook level).
Common Input (all events receive on stdin as JSON)
Tool Events — Additional Input
PreToolUse, PostToolUse, PostToolUseFailure, and PermissionRequest also receive:
SessionStart — Additional Input
Hook Response Patterns
| Pattern | How | Used by |
|---|---|---|
| Add context | Exit 0, stdout text | <code>SessionStart</code>, <code>UserPromptSubmit</code>, <code>SubagentStart</code> |
| Block action | Exit 2, stderr message | <code>PreToolUse</code>, <code>UserPromptSubmit</code>, <code>Stop</code>, <code>SubagentStop</code>, <code>WorktreeCreate</code> |
| Allow/Deny tool | JSON: <code>hookSpecificOutput.permissionDecision</code> | <code>PreToolUse</code> |
| Decision block | JSON: <code>decision: "block"</code> | <code>UserPromptSubmit</code>, <code>PostToolUse</code>, <code>Stop</code>, <code>SubagentStop</code>, <code>ConfigChange</code> |
| Stop execution | JSON: <code>{"continue": false, "stopReason": "..."}</code> | Universal |
| Side effect only | Exit 0, no output | Any event |
MCP Tool Matching
MCP tools follow the pattern
mcp__<server>__<tool>. Matchers are regex patterns.
Hook Types per Event
Not all events support all hook types:
All four types (command, http, prompt, agent): PreToolUse, PostToolUse, PostToolUseFailure, PermissionRequest, Stop, SubagentStop, TaskCompleted, UserPromptSubmit
Command only: ConfigChange, Notification, PreCompact, SessionEnd, SessionStart, SubagentStart, TeammateIdle, WorktreeCreate, WorktreeRemove
Related
enforcement-architecture— four pillars overview with enforcement stackagent-workflow— how agents use the enforcement systemagent-spawn-conventions— spawn axiom and enforcement asymmetry- Claude Code hooks docs — official reference
- Claude Code subagent docs — frontmatter hooks
- Procedures:
sop-hook-block-recovery— recovery procedure when hooks block unexpectedly