Skip to content

[BUG] PreToolUse hook permissionDecision "defer" never resolves under bypassPermissions — tool call silently dies ("Tool execution was interrupted") #82198

Description

@ahmedhamrouni-cpu

Summary

A PreToolUse hook that returns permissionDecision: "defer" (documented as "use normal flow") permanently wedges the tool call when the session runs in bypassPermissions mode. The transcript logs hook_successhook_additional_contexthook_deferred_tool, and then the tool never executes — no tool_result is ever written. The turn ends showing Stopped, and in other occurrences the user-visible message is "Tool execution was interrupted." The model never sees a result, so the work silently dies mid-turn.

Environment

  • Claude Code 2.1.219 (Windows desktop app)
  • Windows 11 Pro 10.0.26200
  • Permission mode: bypassPermissions
  • Model: claude-opus-5
  • Hook: project-level PreToolUse on matcher Edit|Write, powershell.exe script, exits 0

Hook output that triggers it

The hook is warn-only: it should let the tool run and inject a note into context. It printed (single line, exit code 0):

{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"defer","additionalContext":"This path is inside lane 'x' owned by another session. ..."}}

Per https://code.claude.com/docs/en/hooks.md, "defer" is a valid permissionDecision value meaning the normal permission flow should apply. Under bypassPermissions, the normal flow would allow the tool — instead the call is parked and never resolves.

Transcript evidence (session .jsonl, paths sanitized)

The session's last entries — an Edit tool_use that never gets a result:

type=attachment  hook_success            PreToolUse:Edit  toolUseID=toolu_01Rd8...
  stdout: {"hookSpecificOutput":{"additionalContext":"This path is inside lane ...","permissionDecision":"defer","hookEventName":"PreToolUse"}}
type=attachment  hook_additional_context PreToolUse:Edit  toolUseID=toolu_01Rd8...
type=attachment  hook_deferred_tool      toolName=Edit    toolUseID=toolu_01Rd8...
  permissionMode: "bypassPermissions"
--- end of file: no tool_result, no further entries ---

The UI shows the edit group as "Stopped"; the user pressed nothing (no Esc, no new message).

Reproduction

  1. Session in bypassPermissions mode on Windows.
  2. Register a PreToolUse hook (matcher Edit|Write) whose script prints the JSON above and exits 0.
  3. Make Claude edit any file so the hook fires.
  4. The Edit is deferred and never executes; the turn dies.

Intermittent-looking in practice because our hook only emits defer on certain paths — every "random interruption" we chased for two days correlated 1:1 with the hook taking the defer branch.

Expected

"defer" should hand the call to the normal permission evaluation; under bypassPermissions the tool should simply run (with additionalContext injected). At minimum, an unresolved deferred call should fail loudly rather than silently ending the turn.

Workaround

Omit permissionDecision entirely and return only additionalContext (the docs' warn-only example). The tool then executes normally and the context is delivered — confirmed on the same machine/version immediately after the change, hooks otherwise identical.

🤖 Filed with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions