# Hook Events Reference

> All 26 hook events as of April 2026. Source: code.claude.com/docs/en/hooks.md
> Verified 2026-04-19 against research/03-claude-code-changes-config-surfaces.md — no new hook events introduced in v2.1.83–v2.1.111. Sandbox + managed-only flags (2026-04) operate at the settings layer, not as new hook events.

---

## Event Table

| Event | Trigger | Blocking? | Matcher Support | Common Use Cases |
|-------|---------|-----------|-----------------|------------------|
| `SessionStart` | Session begins or resumes | No | `startup`, `resume`, `clear`, `compact` | Inject git branch/env into context; show session state; load external context |
| `InstructionsLoaded` | CLAUDE.md / .claude/rules files are loaded | No | `session_start`, `nested_traversal`, `path_glob_match`, `include`, `compact` | Debug which instruction files loaded; log instruction sources; validate rule sets |
| `UserPromptSubmit` | User submits a prompt | Yes | No matcher | Validate prompt length; inject context; block disallowed prompt patterns; add mandatory context |
| `PreToolUse` | Before any tool executes | Yes | Tool name (e.g., `Bash`, `Write`, `mcp__.*`) | Security validation; confirm destructive ops; log tool calls; rate limiting |
| `PermissionRequest` | Permission dialog appears | Yes | Tool name | Auto-approve known-safe patterns; add approval context; integrate with approval workflows |
| `PermissionDenied` | Auto mode denies a tool call | No (info only) | Tool name | Log denied operations; alert on unexpected denials; track permission patterns |
| `PostToolUse` | Tool completes successfully | No | Tool name | Auto-format after Write/Edit; run linting; update docs; log completions |
| `PostToolUseFailure` | Tool ends in error | No | Tool name | Log failures; send alerts; trigger retry logic; update error tracking |
| `SubagentStart` | Subagent is spawned | No | Agent type (name) | Log agent invocations; inject agent-specific context; record spawn times |
| `SubagentStop` | Subagent finishes | Yes | Agent type (name) | Quality gates (exit 2 to reject); validate agent output; run post-agent checks |
| `TaskCreated` | A task is created in the task list | Yes | No matcher | Validate task format; enforce naming conventions; block disallowed task types |
| `TaskCompleted` | A task is marked complete | Yes | No matcher | Verify completion criteria; run acceptance checks; require sign-off |
| `Stop` | Claude finishes a response turn | Yes | No matcher | Session summaries; commit prompts; send desktop notifications; log turn metadata |
| `StopFailure` | Turn ends in an API error | No | Error type | Alert on API errors; retry logic; log error context |
| `TeammateIdle` | An agent team member has no tasks | Yes | No matcher | Assign next task (exit 2 to keep working); log team status; rebalance work |
| `Notification` | A notification is sent (permission prompt, idle, auth) | No | `permission_prompt`, `idle_prompt`, `auth_success`, `elicitation_dialog` | Desktop notifications; Slack/webhook alerts; mobile push; audio cues |
| `ConfigChange` | A config file changes on disk | Yes | `user_settings`, `project_settings`, `local_settings`, `policy_settings`, `skills` | Validate config changes; block invalid edits; reload dependent processes |
| `CwdChanged` | Working directory changes | No | No matcher | Inject new directory context; update env vars via `$CLAUDE_ENV_FILE`; log navigation |
| `FileChanged` | A watched file changes | No | Filename pattern | Auto-reload when config changes; trigger builds on source change; sync state |
| `WorktreeCreate` | A git worktree is being created | Yes (path return) | No matcher | Custom worktree path via stdout; non-git VCS support; worktree naming conventions |
| `WorktreeRemove` | A git worktree is removed | No | No matcher | Cleanup resources; log worktree lifecycle; update team state |
| `PreCompact` | Before context compaction | No | `manual`, `auto` | Save current state; checkpoint important context; log pre-compact state |
| `PostCompact` | After context compaction | No | `manual`, `auto` | Reinject critical context; validate compaction; log post-compact state |
| `Elicitation` | An MCP server requests user input | Yes | MCP server name | Control which servers can request input; log elicitations; pre-fill responses |
| `ElicitationResult` | User responds to MCP elicitation | Yes | MCP server name | Validate responses; log user input; transform before sending to MCP |
| `SessionEnd` | Session terminates | No | `clear`, `resume`, `logout`, `prompt_input_exit`, `other` | Final session summary; save state; cleanup temp files; send end-of-session report |

---

## Hook Handler Types

| Type | Description | Use When |
|------|-------------|----------|
| `command` | Shell command (bash/powershell) | Fast scripts, file checks, security validation |
| `http` | HTTP POST to endpoint | Remote logging, webhooks, approval systems |
| `prompt` | LLM evaluation (yes/no decision) | Semantic validation that needs language understanding |
| `agent` | Full subagent with tools | Complex validation requiring file reads or multi-step logic |

---

## Handler Configuration Fields

| Field | Type | Description |
|-------|------|-------------|
| `type` | string | `command`, `http`, `prompt`, `agent` |
| `command` | string | Shell command (type: command only) |
| `url` | string | HTTP endpoint (type: http only) |
| `prompt` | string | LLM prompt (type: prompt only) |
| `if` | string | Conditional expression — only fires when true (e.g., `Bash(rm *)`) |
| `timeout` | number | Milliseconds before hook is killed (default: varies) |
| `statusMessage` | string | Message shown in UI while hook runs |
| `async` | bool | `true` = fire and forget, don't wait for result |
| `shell` | string | `"bash"` or `"powershell"` |

---

## Exit Code Semantics

| Exit Code | Blocking Event | Non-Blocking Event |
|-----------|---------------|---------------------|
| `0` | Proceed; JSON on stdout is parsed | Success; JSON on stdout parsed |
| `2` | **Block** — stderr shown to Claude as error | Non-blocking; treated as informational |
| other | Non-blocking; stderr in verbose log only | Non-blocking; stderr in verbose log only |

---

## Blocking Event Output Fields

**PreToolUse** (exit 0):
- `permissionDecision`: `"allow"` / `"deny"` / `"ask"` / `"defer"`
- `updatedInput`: modified tool input
- `additionalContext`: string appended to Claude's context

**PermissionRequest** (exit 0):
- `decision.behavior`: `"allow"` / `"deny"`
- `updatedInput`: modified input
- `updatedPermissions`: modified permission set

**WorktreeCreate** (exit 0):
- stdout: path string OR `hookSpecificOutput.worktreePath`

**SessionStart** (exit 0):
- `additionalContext`: string injected into context
- Or: write env vars to `$CLAUDE_ENV_FILE`

---

## Environment Variables Available in Hooks

| Variable | Available In | Description |
|----------|-------------|-------------|
| `$CLAUDE_PROJECT_DIR` | All hooks | Absolute path to project root |
| `${CLAUDE_PLUGIN_ROOT}` | Plugin hooks | Plugin installation directory |
| `${CLAUDE_PLUGIN_DATA}` | Plugin hooks | Plugin persistent data directory |
| `$CLAUDE_ENV_FILE` | SessionStart, CwdChanged, FileChanged | Path to write env var exports |
| `$CLAUDE_CODE_REMOTE` | All hooks | `"true"` when running in web sessions |

---

## MCP Tool Matcher Patterns

| Pattern | Matches |
|---------|---------|
| `mcp__memory__.*` | All tools from the `memory` server |
| `mcp__.*__write.*` | Any tool named `write*` from any server |
| `mcp__filesystem__read_file` | Specific tool on specific server |
| `mcp__.*` | All MCP tools from all servers |
