Desktop app: PreToolUse hook emitting an unrecognized `permissionDecision` fails the whole tool call with an opaque internal error (CLI ignores it)

Status Open
Maintainer reply None cached
Activity 0 comments · opened Aug 27, 2026

Environment

  • Claude Desktop app 1.37937.3 (macOS, Darwin 25.6.0)
  • Claude Code CLI 2.1.243 (for comparison; not affected)

Summary

If a PreToolUse hook writes a hookSpecificOutput JSON whose permissionDecision is not one of the documented values (allow / deny / ask), the Desktop app fails the entire tool call with an opaque error, while the CLI silently ignores the unrecognized value. With a hook matched on Bash, this makes the Bash tool 100% unusable in Desktop sessions, and nothing in the error output points at hooks as the cause.

Minimal reproduction

Add to ~/.claude/settings.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "printf '%s' '{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"defer\",\"permissionDecisionReason\":\"repro\"}}'",
            "timeout": 10
          }
        ]
      }
    ]
  }
}

Then open a session in the Desktop app and ask for any Bash command (e.g. echo test).

Actual behavior

Every Bash tool call fails: the transcript shows Tool execution was interrupted. and the tool result is [Tool result missing due to internal error]. The underlying command never runs. There is no indication that a hook (or which hook) caused the failure.

Expected behavior

Either of:

  • Lenient parsing: treat an unrecognized permissionDecision as "no opinion" (equivalent to emitting no decision), ideally with a warning naming the hook and the invalid value, or
  • A clear validation error that names the offending hook command and the invalid value, instead of a generic internal error on the tool call.

The hooks documentation defines allow / deny / ask but does not specify behavior for unrecognized values, and the CLI and Desktop currently disagree.

Isolation evidence

  • Hook command /usr/bin/true (no output): Bash works in Desktop.
  • Hook printing the "defer" JSON above: every Bash call fails in Desktop.
  • Same hook emitting valid values (allow / ask), or exiting 0 with no output: works in Desktop.
  • The same "defer"-emitting hook had been running for months under the CLI without issues (value silently ignored).

Impact

A single hook emitting a nonstandard decision value (easy to ship in a hand-written or community hook script) bricks the Bash tool for all Desktop sessions, and the opaque error makes it very hard to trace back to hook configuration.

View original on GitHub ↗