PreToolUse hook returning permissionDecision: 'defer' silently parks the tool and surfaces as '[Tool result missing due to internal error]'

Status Closed — duplicate
Reported on v2.1.221
Maintainer reply None cached
Activity 1 comment · opened Aug 6, 2026 · closed Aug 15, 2026

Summary

When a PreToolUse hook returns permissionDecision: "defer" and the session is flagged isNonInteractiveSession, the tool call is parked and never runs. The model receives [Tool result missing due to internal error] — an opaque message that gives no indication a hook deferred the call.

Two things make this hard to diagnose:

  1. The Claude desktop app is flagged non-interactive even with a human present. So defer — documented in-code as "print-mode only" — is actually honored in a live, interactive-feeling desktop session.
  2. The failure is silent and misattributed. "Internal error" reads like a transport/platform fault, not "your hook parked this call". The interactive path logs a helpful warning (ignoring (defer is print-mode only)); the non-interactive path that actually parks the tool logs nothing the user sees.

This bit AskUserQuestion particularly hard: the decision-card UI never appears, so the human is never asked anything and the agent silently proceeds without an answer.

Repro

  1. Register a PreToolUse hook matching AskUserQuestion that prints:

``json
{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"defer"}}
``

  1. Run in the Claude desktop app (not the terminal CLI).
  2. Have the model call AskUserQuestion.

Expected: the decision card renders, or a clear message explaining the call was deferred by a hook.
Actual: no card, and the model receives [Tool result missing due to internal error].

Removing permissionDecision (or running the same hook in the terminal CLI, where defer is ignored) makes it work.

Observed on Claude Code 2.1.221, macOS 25.5.0. In one transcript history, 3,700+ calls to every other tool resolved 100% while all 8 AskUserQuestion calls returned no result.

Suggested improvements

  • Surface a specific error when a tool is parked by a hook — e.g. "Tool call deferred by PreToolUse hook <name>" — instead of the generic internal-error string.
  • Consider whether AskUserQuestion should be exempt from defer parking, since parking it converts "ask the human" into "silently don't ask".
  • Reconsider whether the desktop app should report isNonInteractiveSession: true when a human is present and able to answer prompts; defer is documented as print-mode only, but this session type gets the print-mode behavior.
  • Optionally warn at hook-registration time that defer is print-mode only.

Found while debugging gstack, whose AskUserQuestion PreToolUse hook emits defer as its "no opinion" signal. Filing separately there.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗