All skills
Skillintermediate

Claude Code Hooks: Exhaustive Reference

This document provides a comprehensive reference for the Claude Code hooks system, including all hook event types, JSON schemas, edge cases, known bugs, and undocumented behaviors.

Claude Code Knowledge Pack7/10/2026

Overview

Claude Code Hooks: Exhaustive Reference

This document provides a comprehensive reference for the Claude Code hooks system, including all hook event types, JSON schemas, edge cases, known bugs, and undocumented behaviors.

Last Updated: January 2026 Claude Code Version Coverage: v1.0.38 through v2.1.1


Table of Contents

  1. Hook Event Types
  2. Tool Names and Input Schemas
  3. Configuration Format
  4. Hook Input JSON Schema
  5. Hook Output JSON Schema
  6. Permission Decision Types
  7. Exit Code Behavior
  8. Error Handling
  9. Async and Parallel Execution
  10. Version History and Changelog
  11. Known Bugs and Issues
  12. Edge Cases and Gotchas
  13. Undocumented Behavior

Hook Event Types

Claude Code provides 11 hook events covering the complete session lifecycle:

EventTriggerMatcher SupportPrimary Use Cases
PreToolUseBefore tool executionYesValidation, modification, approval/denial
PostToolUseAfter successful tool completionYesLogging, formatting, analysis
PostToolUseFailureAfter tool execution failsYesError handling, retry logic
PermissionRequestBefore permission dialog shownYesAuto-approve/deny permission requests
UserPromptSubmitWhen user submits a promptNoContext injection, prompt validation
NotificationWhen Claude sends notificationsPartialLogging, custom reactions
StopMain agent finishes respondingNoCompleteness validation, force continuation
SubagentStopSubagent finishesNoTask validation, output quality checks
SubagentStartSubagent spawns (v2.0.64+)NoAgent lifecycle tracking
PreCompactBefore context compactionNoTranscript backup, context preservation
SessionStartSession begins or resumesNoEnvironment setup, context loading
SessionEndSession terminatesNoCleanup, state saving, logging

Event Details

PreToolUse

  • When: After Claude creates tool parameters, before execution
  • Can: Block, allow, modify tool inputs, request user confirmation
  • Introduced: v2.0.38
  • Input modification: v2.0.10+

PostToolUse

  • When: Immediately after a tool completes successfully
  • Can: Provide feedback to Claude, log results, trigger follow-up actions
  • Note: tool_result field available in input

PostToolUseFailure

  • When: After a tool execution fails
  • Can: Handle errors, suggest retries
  • Documentation: Sparse; mentioned in Agent SDK but not main hooks docs

PermissionRequest

  • When: Before permission dialog is shown to user
  • Can: Auto-approve or deny on behalf of user
  • Introduced: v2.0.45
  • Warning: Race condition bug exists (see Known Bugs)

UserPromptSubmit

  • When: User submits a prompt, before Claude processes it
  • Can: Block prompts, inject context via additionalContext
  • Note: stdout is added to context (unlike other hooks)

Notification

  • When: Claude Code sends a notification
  • Matchers: permission_prompt and other notification types
  • Payload includes: message, notification_type

Stop / SubagentStop

  • When: Agent/subagent finishes responding
  • Can: Force continuation, validate completeness
  • Split: v2.0.42 separated Stop and SubagentStop

SubagentStart

  • When: Subagent spawns via Task tool
  • Introduced: v2.0.64 (November 19, 2025)
  • Payload: agent_id, parent_agent_id, subagent_type, description

PreCompact

  • When: Before context compaction/summarization
  • Use: Last chance to preserve critical information
  • Introduced: v2.0.30

SessionStart / SessionEnd

  • When: Session lifecycle boundaries
  • SessionStart special: Can persist variables via $CLAUDE_ENV_FILE
  • SessionEnd: Supports systemMessage (v2.1.0+)

Tool Names and Input Schemas

Claude Code has 16+ built-in tools. Hook matchers must use exact tool names (case-sensitive).

Complete Tool List

File Operations

ToolDescriptionKey Input Parameters
ReadRead files (images, PDFs, notebooks)file_path, offset?, limit?
WriteCreate/overwrite filesfile_path, content
EditSingle find-and-replacefile_path, old_string, new_string, replace_all?
MultiEditMultiple sequential editsfile_path, edits[] (array of edit operations)
NotebookEditEdit Jupyter cellsnotebook_path, new_source, cell_id?, cell_type?, edit_mode?
LSList directory contentspath, ignore?
GlobFile pattern matchingpattern, path?
GrepContent search (ripgrep)pattern, path?, output_mode?, glob?, type?, -A?, -B?, -C?, -i?, -n?, multiline?, head_limit?

Execution

ToolDescriptionKey Input Parameters
BashShell commandscommand, description?, timeout?, run_in_background?
BashOutputGet background shell outputbash_id, filter?
KillShellTerminate background shellshell_id

Web

ToolDescriptionKey Input Parameters
WebFetchFetch and analyze URLsurl, prompt
WebSearchWeb searchquery, allowed_domains?, blocked_domains?

Task Management

ToolDescriptionKey Input Parameters
TaskLaunch subagentssubagent_type, prompt, description
TodoWriteManage task liststodos[] (with content, status, activeForm)
ExitPlanModeExit planning modeplan
SkillExecute user-defined skillsskill, args?
SlashCommandExecute slash commandscommand

IDE Integration

ToolDescriptionKey Input Parameters
getDiagnosticsVS Code diagnosticsuri?
executeCodeJupyter kernel executioncode

MCP Tool Naming Convention

MCP (Model Context Protocol) tools follow this pattern:

mcp__<server_name>__<tool_name>

Examples:

  • mcp__github__create_issue
  • mcp__memory__retrieve_memory
  • mcp__filesystem__read_file

Matcher patterns for MCP tools:

"matcher": "mcp__memory__.*"      // All tools from memory server
"matcher": "mcp__.*"              // All MCP tools
"matcher": "mcp__github__create_issue"  // Specific tool

Configuration Format

Configuration Locations (Precedence Order)

  1. .claude/settings.local.json (local, not committed)
  2. .claude/settings.json (project-level, shared)
  3. ~/.claude/settings.json (user-level)

Settings File Format

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "/path/to/script.sh",
            "timeout": 60
          }
        ]
      }
    ],
    "Stop": [
      {
        "hooks": [
          {
            "type": "prompt",
            "prompt": "Verify all tasks are complete: $ARGUMENTS",
            "timeout": 30
          }
        ]
      }
    ]
  }
}

Plugin Format (hooks/hooks.json)

{
  "description": "Brief explanation (optional)",
  "hooks": {
    "PreToolUse": [...],
    "Stop": [...]
  }
}

Hook Types

TypeDescriptionDefault Timeout
commandBash command execution60 seconds
promptLLM-based evaluation (Haiku)30 seconds

Matcher Syntax

PatternMatches
"Write"Exact match (case-sensitive)
`"Write\Edit"`
"*" or ""All tools
"Bash(npm test*)"Argument patterns with wildcards
"mcp__memory__.*"Regex patterns

Important: Matchers are case-sensitive. "bash" will NOT match "Bash".

Configuration Options

FieldTypeDefaultDescription
matcherstring"*"Tool name pattern
hooksarrayrequiredArray of hook definitions
typestringrequired"command" or "prompt"
commandstring-Shell command (for type: command)
promptstring-LLM prompt (for type: prompt)
timeoutnumber60/30Seconds before timeout
oncebooleanfalseRun only once per session

Component-Scoped Hooks (v2.1.0+)

Hooks can be defined in Skills, subagents, and slash commands via frontmatter:

---
hooks:
  PreToolUse:
    - matcher: "Write"
      hooks:
        - type: command
          command: "./validate.sh"
---

These hooks are scoped to the component's lifecycle and auto-cleanup when finished.


Hook Input JSON Schema

All hooks receive JSON via stdin with these common fields:

Common Fields (All Hooks)

{
  "session_id": "abc123",
  "transcript_path": "/Users/.../.claude/projects/.../transcript.jsonl",
  "cwd": "/Users/lily/project",
  "permission_mode": "default",
  "hook_event_name": "PreToolUse"
}
FieldTypeDescription
session_idstringUnique session identifier
transcript_pathstringPath to conversation JSONL transcript
cwdstringCurrent working directory
permission_modestring"default", "plan", "acceptEdits", "dontAsk", "bypassPermissions"
hook_event_namestringThe hook event type

Tool-Related Hooks (PreToolUse, PostToolUse, PermissionRequest)

Additional fields:

{
  "tool_name": "Write",
  "tool_input": {
    "file_path": "/path/to/file.txt",
    "content": "file content"
  },
  "tool_use_id": "toolu_abc123"
}

PostToolUse Additional Fields

{
  "tool_result": "Success: file written"
}

UserPromptSubmit

{
  "user_prompt": "The user's submitted text"
}

Stop / SubagentStop

{
  "reason": "Task completed"
}

SubagentStart (v2.0.64+)

{
  "agent_id": "agent_xyz",
  "parent_agent_id": "agent_abc",
  "subagent_type": "general-purpose",
  "description": "Research task"
}

SessionStart Additional

{
  "agent_type": "custom-agent"
}

Notification

{
  "message": "Claude needs your permission to use Bash",
  "notification_type": "permission_prompt"
}

Environment Variables Available

VariableDescriptionAvailability
CLAUDE_PROJECT_DIRProject root pathAll hooks
CLAUDE_PLUGIN_ROOTPlugin directoryPlugin hooks
CLAUDE_CODE_REMOTESet if remote contextAll hooks
CLAUDE_ENV_FILEFor persisting variablesSessionStart only
CLAUDE_CODE_ENTRYPOINTEntry point (e.g., "cli")All hooks

Hook Output JSON Schema

Hooks communicate via stdout with optional JSON structure.

Universal Output Fields

{
  "continue": true,
  "stopReason": "Optional message when continue=false",
  "suppressOutput": false,
  "systemMessage": "Message shown to USER (not Claude)"
}
FieldTypeDefaultDescription