[BUG] PermissionRequest hook allow is silently ignored for ExitPlanMode unless updatedInput is provided (2.1.246)

Status Open
Reported on v2.1.246
Maintainer reply None cached
Activity 0 comments · opened Aug 29, 2026

What's Wrong?

A PermissionRequest hook that responds with a plain allow decision is silently ignored for the ExitPlanMode tool. The plan-approval dialog stays open and the session remains blocked, even though the hook exited 0 with a valid decision payload.

This is the same symptom as #15755, which was reported fixed in v2.1.7. It is either a regression, or the fix requires an undocumented extra field (see analysis below).

Environment

  • Claude Code 2.1.246 (bundled with the Claude desktop app, macOS; session runs with --permission-prompt-tool stdio)
  • Hook registered via a plugin's hooks/hooks.json:

``json
"PermissionRequest": [
{ "hooks": [ { "type": "command", "command": "python3 \"${CLAUDE_PLUGIN_ROOT}/run_hook.py\"", "timeout": 900 } ] }
]
``

Repro

  1. Enter plan mode, let Claude call ExitPlanMode.
  2. The PermissionRequest hook fires (confirmed — our hook posted the request to Slack).
  3. ~11 minutes later the hook prints the documented allow payload to stdout and exits 0:

``json
{"hookSpecificOutput": {"hookEventName": "PermissionRequest", "decision": {"behavior": "allow"}}}
``

  1. Expected (per the hooks guide, "Auto-approve specific permission prompts"): plan mode exits and the previous permission mode is restored.
  2. Actual: nothing happens. The 3-option plan-approval dialog remains, the turn stays blocked on ExitPlanMode (in our transcript: 2h41m, until the user came back and answered the dialog manually). The eventual tool_result was the manual rejection.

The same hook's allow works fine for regular tools (e.g. Bash); deny also works for ExitPlanMode.

Analysis

The current behavior appears intentional in the code: for tools with requiresUserInteraction() (ExitPlanMode, AskUserQuestion), a hook allow without updatedInput is discarded and the flow falls through to the normal dialog. An allow that echoes the original input as updatedInput takes a different path ("Hook satisfied user interaction for <tool> via updatedInput") and appears to be the supported way to approve programmatically. We have adopted that as a workaround (echoing tool_input back as updatedInput) but have not yet confirmed it end-to-end.

If the updatedInput requirement is by design, it would be great to have it documented in the hooks guide — the current docs state that a plain allow exits plan mode, which is what #15755's resolution also implied.

What Should Happen?

Either:

  • a plain {"behavior": "allow"} from a PermissionRequest hook approves ExitPlanMode (docs' current promise), or
  • the docs explicitly state that requiresUserInteraction tools need updatedInput in the allow decision.

Refs: #15755 (locked; same symptom, reported fixed in 2.1.7)

View original on GitHub ↗