Repository navigation
Claude Code Hooks Config
xsyetopz edited this page Oct 19, 2026
·
1 revision
Hook config decides which hooks run, when they run, and what happens when one fails.
A matcher picks the events, an if filter narrows them to some tool calls, and timeout and onFailure set the limits.
For example, "matcher": "Bash" with "if": "Bash(git push *)" runs a hook only for git push commands.
| Mark | Item | What it does | How it works | Where it can be used | Source |
|---|---|---|---|---|---|
| ✅ |
"*", "", or no matcher
|
Match all | The group runs on every occurrence | All events | Hooks Reference |
| ✅ | Letters, digits, _, -, space, ,, | only |
Exact string or list |
Edit|Write and Edit, Write match either name. mcp__memory alone matches no tool |
All events with a matcher | Hooks Reference |
| ✅ | Any other character | JavaScript regex, unanchored | Tested with RegExp.prototype.test. Use ^ and $ for a whole match |
All events with a matcher | Hooks Reference |
| ✅ |
FileChanged and StopFailure
|
Narrower exact set | Only letters, digits, _, and |. A hyphen, space, or comma makes it a regex |
Those two events | Hooks Reference |
| ✅ | Matcher on an event without one | Silently ignored | No error | The no-matcher events below | Hooks Reference |
| Mark | Item | What it does | How it works | Where it can be used | Source |
|---|---|---|---|---|---|
| ✅ | Tool name | Filters tool events |
Bash, Edit|Write, mcp__.*. Plugin MCP tools are mcp__plugin_<plugin>_<server>__<tool>
|
PreToolUse, PostToolUse, PostToolUseFailure, PermissionRequest, PermissionDenied
|
Hooks Reference |
| ✅ | Start source |
startup, resume, clear, compact, fork
|
fork needs 2.1.214 |
SessionStart |
Hooks Reference |
| ✅ | CLI flag |
init, maintenance
|
Setup |
Hooks Reference | |
| ✅ | End reason |
clear, resume, logout, prompt_input_exit, other
|
SessionEnd |
Hooks Reference | |
| ✅ | Notification type | Types are on Prompt Events | Notification |
Hooks Reference | |
| ✅ | Agent type |
general-purpose, Explore, Plan, custom names |
A plugin name my-plugin:reviewer is a regex. Write ^my-plugin:reviewer$
|
SubagentStart, SubagentStop
|
Hooks Reference |
| ✅ | Trigger |
manual, auto
|
PreCompact, PostCompact
|
Hooks Reference | |
| ✅ | Target model | Canonical name of to_model without [1m]
|
If no canonical name is known, every hook runs |
PreModelSwitch, PostModelSwitch
|
Hooks Reference |
| ✅ | Config source |
user_settings, project_settings, local_settings, policy_settings, skills
|
ConfigChange |
Hooks Reference | |
| ✅ | Add source |
slash_command, register_repo_root
|
DirectoryAdded |
Hooks Reference | |
| ✅ | File names | Literal names to watch, split on |. Then filters by basename |
The matcher also builds the watch list | FileChanged |
Hooks Reference |
| Error type |
rate_limit, overloaded, authentication_failed, oauth_org_not_allowed, account_on_hold, billing_error, invalid_request, model_not_found, server_error, max_output_tokens, cloud_credential_error, unknown
|
The type verification_required is in the bundle type SDKAssistantMessageError and not in the docs list |
StopFailure |
Hooks Reference, StopFailureHookInput
|
|
| ✅ | Load reason |
session_start, nested_traversal, path_glob_match, include, compact
|
InstructionsLoaded |
Hooks Reference | |
| ✅ | Command name | Skill or command names | UserPromptExpansion |
Hooks Reference | |
| ✅ | MCP server name | Configured server names |
Elicitation, ElicitationResult
|
Hooks Reference | |
| ✅ | No matcher | Always fires |
UserPromptSubmit, PostToolBatch, Stop, TeammateIdle, TaskCreated, TaskCompleted, WorktreeCreate, WorktreeRemove, MessageDisplay, CwdChanged
|
Hooks Reference |
| Mark | Item | What it does | How it works | Where it can be used | Source |
|---|---|---|---|---|---|
| ✅ | if |
One permission rule, such as Bash(git *) or Edit(*.ts)
|
Only the five tool events read it. On any other event the hook never runs. No &&, no list |
Handler field | Hooks Reference |
| ✅ | Bash patterns | Checked on each subcommand | Leading VAR=value is stripped. $() and backticks are checked. If the command cannot be parsed, the hook runs |
Bash |
Hooks Reference |
| ✅ | File patterns | Edit(src/**) |
Matches only src in the working directory. Use **/src/** for any depth. This changed in 2.1.214 |
File tools | Hooks Reference |
| Mark | Item | What it does | How it works | Where it can be used | Source |
|---|---|---|---|---|---|
| ✅ | Default timeout
|
600 s for command, http, mcp_tool. 30 s for prompt. 60 s for agent
|
A timed-out hook is canceled and its output dropped | All handlers | Hooks Reference |
| ✅ | Lower defaults | 30 s on UserPromptSubmit, PreModelSwitch, PostModelSwitch. 10 s on MessageDisplay
|
For command, http, mcp_tool
|
Those events | Hooks Reference |
| ✅ |
SessionEnd budget |
1.5 s shared by all hooks | Raised to the largest per-hook timeout in settings, up to 60 s. Plugin timeouts do not raise it |
SessionEnd |
Hooks Reference |
| ✅ |
PreModelSwitch timeout |
A timed-out hook blocks the switch | PreModelSwitch |
Hooks Reference | |
| ✅ |
PreToolUse timeout |
A timed-out command, http, or mcp_tool hook does not block |
Use onFailure: "block" to block. An SDK callback that times out blocks |
PreToolUse |
Hooks Reference |
| 🔍 | asyncTimeout |
A first reply of {"async":true,"asyncTimeout":ms} moves a command hook to the background and sets its time limit |
Default 15000 ms. Only the Agent SDK pages name it, and the Hooks Reference does not | Command hook stdout | bundle, Agent SDK Hooks |
| Mark | Item | What it does | How it works | Where it can be used | Source |
|---|---|---|---|---|---|
| ✅ | onFailure: "continue" |
Default. The action goes on after a failure | Failure means: cannot start, timeout, exit code other than 0 or 2, invalid JSON, or HTTP non-2xx |
command, http
|
Hooks Reference |
| ✅ | onFailure: "block" |
A failure counts as exit 2 | Error text has blocking because onFailure is "block" after the word failed
|
command, http
|
Hooks Reference, bundle |
| 🔍 |
onFailure has no effect |
On async hooks and on Stop, SubagentStop, TaskCompleted, TeammateIdle
|
The field text in the bundle says so. The Hooks Reference does not | Those cases | bundle |
| ✅ | Windows without Git Bash | A shell-form PreToolUse or PermissionRequest hook that fails can block |
Set shell: "powershell" or use exec form and onFailure
|
Windows | Hooks Reference, bundle |
| ✅ | refusing to honor the suspect capture |
A background process that keeps stdout open after an allow blocks the call | Redirect output of background children | command |
Hooks Reference, bundle |
| 🔍 | CLAUDE_CODE_RESTRICT_PERSONAL_CONFIG |
Own hooks in user files must succeed. Their grant and rewrite fields are dropped | Bundle messages: blocking because it is one of the user's own hooks and ignored ... (CLAUDE_CODE_RESTRICT_PERSONAL_CONFIG)
|
PreToolUse, PermissionRequest, PreModelSwitch, UserPromptSubmit, UserPromptExpansion
|
bundle |
| Mark | Item | What it does | How it works | Where it can be used | Source |
|---|---|---|---|---|---|
| ✅ | CLAUDE_PROJECT_DIR |
Project root where the session started | Stays fixed in a worktree. cwd in the input follows Claude |
Hooks, stdio MCP servers, plugin LSP | Hooks Reference |
| ✅ |
CLAUDE_PLUGIN_ROOT, CLAUDE_PLUGIN_DATA
|
Plugin install dir and data dir | Replaced in command and args. Also exported |
Plugin hooks | Hooks Reference |
| ✅ | CLAUDE_PLUGIN_OPTION_<KEY> |
A plugin userConfig option |
Use in shell form. ${user_config.*} works only in exec form |
Plugin hooks | Hooks Reference |
| ✅ | CLAUDE_ENV_FILE |
File of export lines that later Bash commands source |
Append with >>. Not set for PowerShell hooks |
SessionStart, Setup, CwdChanged, FileChanged
|
Hooks Reference |
| ✅ | CLAUDE_EFFORT |
Effort level of the turn | Also in Bash | Hook commands |
Hooks Reference, BaseHookInput.effort
|
| ✅ | CLAUDE_CODE_REMOTE |
"true" in remote web environments |
Unset in the local CLI | Hooks | Hooks Reference |
| ✅ | CLAUDE_CODE_BRIDGE_SESSION_ID |
Remote Control session ID | Set from 2.1.199 while connected | Hooks | Hooks Reference |
| ✅ | Inherited env | The parent env minus OTEL_*
|
CLAUDE_CODE_SUBPROCESS_ENV_SCRUB=1 strips more. HIPAA sessions drop Anthropic credentials |
Hooks | Hooks Reference |
| ✅ | No CLAUDE_MODEL
|
Does not exist | Use PostModelSwitch and to_model
|
Hooks | Hooks Reference |
| ✅ |
CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS, CLAUDE_CODE_STOP_HOOK_BLOCK_CAP
|
SessionEnd budget. Stop continuation cap (default 8) |
See Env Vars | Hook runtime | Hooks Reference |
| ✅ |
CLAUDE_CODE_DISABLE_PERMISSION_PROMPT_NOTIFY_HOOKS, CLAUDE_CODE_DISABLE_FILE_MENTIONS, CLAUDE_CODE_GIT_BASH_PATH, MCP_TIMEOUT
|
Turn off permission_prompt in SDK hosts. Stop @ insertion. Git Bash path. MCP wait |
Hook runtime | Hooks Reference | |
| 🔍 | CLAUDE_CODE_HOOKS_SAME_THREAD |
Run function hooks on the main thread, not in a worker | Bundle returns same-thread or worker. A mod test helper in the bundle sets it |
Mods | bundle |
| 🔍 |
CLAUDE_CODE_DISABLE_HOOK_FORWARDING, CLAUDE_CODE_RESUME_SESSIONSTART_HOOKS_WAIT_MS, DISABLE_BRIEF_MODE_STOP_HOOK
|
Names found in the env table of the bundle | Effect not verified | Not verified | bundle env table |
| Mark | Item | What it does | How it works | Where it can be used | Source |
|---|---|---|---|---|---|
| ✅ | hooks |
The event map | Merges across levels | Settings | schema claude-code-settings.json
|
disableAllHooks |
Turns hooks off | The schema also says it stops the statusLine command, but the Hooks Reference names only hooks. Managed hooks stay unless set in managed settings |
Settings, --settings
|
schema, Hooks Reference | |
| ✅ | allowManagedHooksOnly |
Only managed hooks and managed-enabled plugin hooks run | Also narrows statusLine, fileSuggestion, subagentStatusLine
|
Managed settings | schema, Hooks Reference |
| ✅ | allowedHttpHookUrls |
URL allowlist for http hooks |
* wildcard. Empty array blocks all |
All levels, arrays merge | schema |
| ✅ | httpHookAllowedEnvVars |
Env name allowlist for header values | Intersected with allowedEnvVars
|
All levels, arrays merge | schema |
| ✅ | Workspace trust | Settings hooks wait for the trust dialog |
-p and SDK sessions treat the folder as trusted. Project subagent hooks need the dialog |
Interactive | Hooks Reference |
| ✅ |
/hooks menu |
Read-only browser of hooks | Shows the source of each | Interactive | Hooks Reference |
| ✅ | Debug | claude --debug-file <path> |
CLAUDE_CODE_DEBUG_LOG_LEVEL=verbose adds matcher lines |
CLI | Hooks Reference |
-
Hooks Reference,
schemas/claude-code-settings.json,schemas/claude-code-managed-settings.json.
- Not verified: effect of
CLAUDE_CODE_DISABLE_HOOK_FORWARDING,CLAUDE_CODE_RESUME_SESSIONSTART_HOOKS_WAIT_MS, andDISABLE_BRIEF_MODE_STOP_HOOK. - Not verified in the bundle: the default timeout values.
claudetto
- Start
- Slices
- Add-Ons
- Reference
- Rationale
- Evidence
- Development
Claude Code 2.1.303
- Start
- Models and Context
- Configure
- Extend
- Findings