[DOCS] PermissionRequest docs do not clearly define `decision.message` behavior for allow vs deny paths

Resolved 💬 2 comments Opened Feb 18, 2026 by coygeek Closed Mar 8, 2026

Documentation Type

Unclear/confusing documentation

Documentation Location

https://code.claude.com/docs/en/hooks

Section/Topic

  • PermissionRequest event: "PermissionRequest decision control" field table
  • Decision control summary and examples for tool permission events

Current Documentation

The PermissionRequest field table says:

| Field | Description |
|------|-------------|
| behavior | "allow" grants the permission, "deny" denies it |
| updatedInput | For "allow" only |
| updatedPermissions | For "allow" only |
| message | For "deny" only: tells Claude why the permission was denied |
| interrupt | For "deny" only |

The same section also presents an "allow" example, but does not show how user-visible messaging should work in that path.

What's Wrong or Missing?

A. The docs do not define validation behavior for extra fields on "allow"

It is unclear whether decision.message is:

  • invalid for "allow" and causes rejection,
  • accepted but ignored for "allow",
  • or accepted and surfaced somewhere (user UI, Claude transcript, logs).

B. There is no explicit matrix of field validity by behavior

The table has per-field notes, but it does not specify parser/validation behavior when a field appears outside its documented behavior. Hook authors need that to avoid silent no-ops.

C. Real-world usage makes this ambiguity visible

Community hooks for PermissionRequest + ExitPlanMode often include decision.message with "behavior": "allow" (for example: https://github.com/yigitkonur/hooks-claude-approve), so users need authoritative clarification on whether this is supported or merely tolerated.

Suggested Improvement

In PermissionRequest decision control, add explicit behavior semantics:

  1. A validity matrix for each field by behavior (allow, deny), including whether out-of-scope fields are ignored or treated as errors.
  2. Two canonical examples:
  • allow example with only supported fields
  • deny example showing message and interrupt
  1. A short note on where message appears (Claude feedback vs user-facing UI) and whether that differs by behavior.

If message is intentionally deny-only, state clearly that on "allow" it is ignored (or invalid), so users do not rely on undefined behavior.

Impact

Medium - Makes feature difficult to understand

Additional Context

Affected Pages:

| Page | Section | Issue |
|------|---------|-------|
| https://code.claude.com/docs/en/hooks | PermissionRequest decision control | message listed as deny-only, but behavior on allow path is not explicitly defined |
| https://code.claude.com/docs/en/hooks | Decision control examples | No deny-path PermissionRequest example showing message/interrupt |

Total scope: 1 page affected (with two related sections)

Related issue in same area: matcher/tool-name completeness for PermissionRequest and PreToolUse (drafted separately).

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗