[DOCS] Missing PermissionRequest hook details in Hooks Guide and Input Reference schema

Status Closed — not planned
Maintainer reply None cached
Activity 11 comments · opened Nov 18, 2025 · closed Mar 18, 2026

Documentation Type

Missing documentation (feature not documented)

Documentation Location

docs/en/hooks-guide.md docs/en/hooks.md

Section/Topic

  • hooks-guide.md: "Hook Events Overview" - hooks.md: "Hook Input" section

Current Documentation

In docs/en/hooks-guide.md under Hook Events Overview, the list currently reads:

PreToolUse: Runs before tool calls (can block them) PostToolUse: Runs after tool calls complete UserPromptSubmit: Runs when the user submits a prompt... Notification: Runs when Claude Code sends notifications Stop: Runs when Claude Code finishes responding SubagentStop: Runs when subagent tasks complete PreCompact: Runs before Claude Code is about to run a compact operation SessionStart: Runs when Claude Code starts a new session... * SessionEnd: Runs when Claude Code session ends

In docs/en/hooks.md, while PermissionRequest is mentioned in the Configuration and Output sections, it is completely missing from the Hook Input section, which lists inputs for all other hooks (PreToolUse Input, PostToolUse Input, Notification Input, etc.).

What's Wrong or Missing?

The PermissionRequest hook was introduced in v2.0.45 (according to the Changelog), but the documentation is incomplete:

  1. It is missing from the high-level list in the Hooks Guide, making it difficult for new users to know the feature exists.
  2. Critically, the Reference documentation is missing the PermissionRequest Input JSON schema. Developers cannot implement this hook without knowing what fields are passed to stdin (e.g., does it receive tool_input? tool_name? cwd?).

Suggested Improvement

In docs/en/hooks-guide.md:*
Add PermissionRequest to the overview list:

* PermissionRequest: Runs when the permission system requires user confirmation (can auto-approve or deny)

In docs/en/hooks.md:
Add a new section under Hook Input detailing the JSON schema. Based on the tool's behavior, it should likely look similar to this:

PermissionRequest Input

{
  "session_id": "abc123",
  "transcript_path": "/Users/.../.claude/projects/.../transcript.jsonl",
  "cwd": "/Users/...",
  "permission_mode": "default",
  "hook_event_name": "PermissionRequest",
  "tool_name": "Bash",
  "tool_input": {
    "command": "npm install"
  }
}

Impact

High - Prevents users from using a feature

Additional Context

  • This feature was highlighted in Changelog 2.0.45: "Added PermissionRequest hook to automatically approve or deny tool permission requests with custom logic"
  • The "Decision Control" output format is documented, but the Input format is missing.

View original on GitHub ↗

11 Comments

edsonbrusque · 9 months ago

Also, why this hook doesn't fire a command?

The "Stop" hook works on my environment (WSL) but "PermissionRequest" doesn't.

"Stop": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "powershell.exe -Command \"(New-Object Media.SoundPlayer 'C:\\Media\\chord.wav').PlaySync()\""
          }
        ]
      }
    ],
    "PermissionRequest": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "powershell.exe -Command \"(New-Object Media.SoundPlayer 'C:\\Media\\chimes.wav').PlaySync()\""
          }
        ]
      }
    ],
McBenac · 8 months ago

I can confirm this issue. PermissionRequest hook does not trigger in VSCode extension on Windows 11 either.

Tested with:

  • matcher: "*"
  • Simple PowerShell command to play a sound

PreToolUse hook works fine with identical config, but triggers on ALL tool calls (including auto-approved), making it unsuitable for notifications when human input is required.

Use case: Running multiple Claude Code sessions and needing audio alert when permission dialog appears.

NubeBuster · 7 months ago

The hooks documentation is not maintained very well and this confuses very much. Where can we rely if not on the docs nor the schema?

snoolord · 7 months ago

+1 to @McBenac would love to have this fixed for vscode extension so that it fires PermissionRequest or atleast Notification when it's asking for user permission.

coygeek · 7 months ago

Issue #11891 Verification

Title: [DOCS] Missing PermissionRequest hook details in Hooks Guide and Input Reference schema
Issue Date: 2025-11-18
Verification Date: 2026-01-23
Status: PARTIALLY FIXED

---

Issue Summary

I reported that PermissionRequest hook documentation was incomplete in two ways:

  1. Missing from the Hook Events Overview in hooks-guide.md
  2. Missing PermissionRequest Input JSON schema in hooks.md (the reference documentation)

---

Verification Results

Claim 1: PermissionRequest missing from Hook Events Overview

Status: FIXED

In code.claude.com/docs/en/hooks-guide.md lines 42-43, PermissionRequest is now listed:

* **PermissionRequest**: Runs when a permission dialog is shown (can allow or deny)

Verdict: Anthropic added PermissionRequest to the Hook Events Overview. This part of the issue is resolved.

---

Claim 2: PermissionRequest Input schema missing from hooks.md

Status: STILL EXISTS

In code.claude.com/docs/en/hooks.md, the Hook Input section (lines 527-809) contains detailed JSON schema entries for:

| Hook Event | Lines | Status |
|------------|-------|--------|
| PreToolUse Input | 546-648 | Documented |
| PostToolUse Input | 650-672 | Documented |
| Notification Input | 674-686 | Documented |
| UserPromptSubmit Input | 688-699 | Documented |
| Stop Input | 701-716 | Documented |
| SubagentStop Input | 718-733 | Documented |
| PreCompact Input | 735-749 | Documented |
| Setup Input | 751-764 | Documented |
| SessionStart Input | 766-780 | Documented |
| SubagentStart Input | 782-796 | Documented |
| SessionEnd Input | 798-809 | Documented |
| PermissionRequest Input | N/A | MISSING |

There is NO ### PermissionRequest Input section. Developers implementing PermissionRequest hooks cannot determine from the reference documentation what JSON fields are passed to stdin.

What IS documented:

  • PermissionRequest appears in the Hook lifecycle table (line 24)
  • ### PermissionRequest under Hook Events (lines 361-366) explains WHEN it fires
  • #### PermissionRequest Decision Control (lines 935-953) explains OUTPUT format

What is NOT documented:

  • The INPUT schema (what JSON fields the hook receives via stdin)

Verdict: The commenter coygeek's update from the issue thread is accurate. Part 2 remains unresolved.

---

Current State

| Claim | Status |
|-------|--------|
| PermissionRequest in Hook Events Overview | FIXED |
| PermissionRequest Input schema in hooks.md | STILL EXISTS |

---

Suggested Fix

Add a ### PermissionRequest Input section after line 648 (after PreToolUse Input) in hooks.md:

Before: (current - no section exists)

After:

### PermissionRequest Input

Triggered when the permission dialog appears for a tool call. The input mirrors `PreToolUse` with the same `tool_name` and `tool_input` fields.

```json
{
  "session_id": "abc123",
  "transcript_path": "/Users/.../.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
  "cwd": "/Users/...",
  "permission_mode": "default",
  "hook_event_name": "PermissionRequest",
  "tool_name": "Bash",
  "tool_input": {
    "command": "npm install",
    "description": "Install dependencies"
  },
  "tool_use_id": "toolu_01ABC123..."
}

The tool_input schema varies by tool. See [PreToolUse Input](#pretooluse-input) for tool-specific examples.


---

## References

- Mirror file: `code.claude.com/docs/en/hooks.md`
  - Hook lifecycle table: line 24 (includes PermissionRequest)
  - Hook Input section: lines 527-809 (missing PermissionRequest Input)
  - PermissionRequest Decision Control: lines 935-953 (output documented)
- Mirror file: `code.claude.com/docs/en/hooks-guide.md`
  - Hook Events Overview: lines 37-55 (now includes PermissionRequest)
yigitkonur · 6 months ago

spent a few mins on tracing the wire to piece this together. here's what PermissionRequest actually sends + plus a ready-to-paste auto-approver (this was my usecase to auto-approve)

---

what PermissionRequest receives

stdin delivers this json:

{
  "session_id": "abc123-def4-5678-ghij-klmnopqrstuv",
  "transcript_path": "/Users/you/.claude/projects/-Users-you-my-project/abc123.jsonl",
  "cwd": "/Users/you/my-project",
  "permission_mode": "plan",
  "hook_event_name": "PermissionRequest",
  "tool_name": "ExitPlanMode",
  "tool_input": {
    "allowedPrompts": [
      { "tool": "Bash", "prompt": "run tests" },
      { "tool": "Bash", "prompt": "install deps" }
    ],
    "plan": "# Plan: Implement Feature X\n\n## Context\n\n..."
  }
}

field breakdown:

  • session_id — uuid for the current session
  • transcript_path — full path to the jsonl log
  • cwd — working directory at time of request
  • permission_mode — one of default / plan / bypassPermissions
  • tool_name — the tool requesting permission (Bash, Write, AskUserQuestion, etc.)
  • tool_input — exact args passed, same shape as PreToolUse

tool_input varies by tool:

  • ExitPlanMode{ plan: "...", allowedPrompts: [...] }
  • Bash{ command: "npm install", description: "..." }
  • Write{ file_path: "...", content: "..." }
  • AskUserQuestion{ questions: [...] }

one key distinction from PreToolUse: PermissionRequest only fires when claude is actually blocked waiting on you — not on every tool call.

---

responding

stdout controls the outcome.

allow:

{"hookSpecificOutput":{"hookEventName":"PermissionRequest","decision":{"behavior":"allow","message":"auto-approved by hook"}}}

deny:

{"hookSpecificOutput":{"hookEventName":"PermissionRequest","decision":{"behavior":"deny","message":"blocked by policy"}}}

no output → normal dialog appears as usual.

---

matcher patterns

{
  "matcher": "ExitPlanMode",
  "hooks": [{ "type": "command", "command": "~/.claude/hooks/auto-approve-plan.sh" }]
}

common matchers: ExitPlanMode, Bash, Write|Edit, empty string = catch all.

---

stop vs. permissionrequest

Stop fires after the user has already responded. PermissionRequest fires the moment the dialog would appear — this is the hook you want for approval flows.

---

auto-approver

~/.claude/hooks/auto-approve-plan.sh:

#!/bin/bash
cat >&-   # drain stdin
cat <<'EOF'
{"hookSpecificOutput":{"hookEventName":"PermissionRequest","decision":{"behavior":"allow","message":"auto-approved by hook"}}}
EOF

settings.json:

{
  "hooks": {
    "PermissionRequest": [
      {
        "matcher": "ExitPlanMode",
        "hooks": [{ "type": "command", "command": "~/.claude/hooks/auto-approve-plan.sh" }]
      }
    ]
  }
}

macos notification-only (no auto-approve):

#!/bin/bash
cat >&-
afplay /System/Library/Sounds/Glass.aiff &
note: always drain stdin (cat >&-) — skipping it will hang the process on windows/wsl.

---

that's the missing page. build whatever approval flow you need. if you wanna see real implementation, check: https://github.com/yigitkonur/hooks-claude-approve

coygeek · 6 months ago

@yigitkonur excellent work. i've submitted a single issue I found.

coygeek · 5 months ago

Issue #11891 Verification

Title: [DOCS] Missing PermissionRequest hook details in Hooks Guide and Input Reference schema
Issue Date: 2025-07-01
Verification Date: 2026-03-17
Status: RESOLVED
Submission Mode: DRAFT ONLY (manual review required before posting/closing)

---

Issue Summary

This issue reports that the PermissionRequest hook type lacked detailed documentation of its input schema, decision control fields, and usage examples.

---

Verification Results

Claim 1: PermissionRequest hook details missing from hooks reference

Status: RESOLVED

At https://code.claude.com/docs/en/hooks, the PermissionRequest event is now documented with:

  • Event description: "When a permission dialog appears"
  • Matcher behavior: "Matches on tool name, same values as PreToolUse"
  • Full input schema with annotated JSON example including tool_name, tool_input, hook_event_name, and permission_suggestions
  • A dedicated "PermissionRequest decision control" subsection documenting decision.behavior (allow/deny), updatedInput, updatedPermissions, message, and interrupt
  • JSON output examples
  • Summary table entry: hookSpecificOutput with decision.behavior (allow/deny)

Claim 2: No usage examples

Status: RESOLVED

At https://code.claude.com/docs/en/hooks-guide, there is now a concrete example using PermissionRequest with ExitPlanMode demonstrating the allow behavior with updatedPermissions.

Verdict: The hooks reference and guide now provide comprehensive PermissionRequest documentation.

---

Current State

| Claim | Status |
|-------|--------|
| Missing input schema | RESOLVED |
| Missing decision control fields | RESOLVED |
| Missing usage examples | RESOLVED |

---

References

---

Conclusion & Recommendation

Primary Concern: PermissionRequest hook lacked input schema, decision fields, and examples.

Resolution Status: RESOLVED

Recommendation: CLOSE

The hooks reference now has a full PermissionRequest section with input schema, all decision control fields, and the hooks guide includes a concrete usage example.

coygeek · 5 months ago

Closing — verified resolved against current docs. See verification comment above.

coygeek · 5 months ago

Correction: The verification comment above incorrectly states "Issue Date: 2025-07-01" — the actual issue date is 2025-11-18. All other content is accurate.

github-actions[bot] · 5 months ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.