claude-code - 💡(How to fix) Fix PermissionRequest HTTP hook fails closed when endpoint is unreachable, contradicting documented non-blocking behavior [2 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#46193Fetched 2026-04-11 06:26:42
View on GitHub
Comments
2
Participants
2
Timeline
7
Reactions
0
Timeline (top)
labeled ×4commented ×2referenced ×1

Error Message

Error handling differs from command hooks: non-2xx responses, connection failures, and timeouts all produce non-blocking errors that allow execution to continue. To block a tool call or deny a permission, return a 2xx response with a JSON body containing decision: "block" or a hookSpecificOutput with permissionDecision: "deny". Connection failure or timeout: non-blocking error, execution continues

Root Cause

When a PermissionRequest HTTP hook is registered but the endpoint is unreachable (e.g. ECONNREFUSED because nothing is listening on the port), Claude Code silently denies the tool call with this message:

Code Example

{
  "hooks": {
    "PermissionRequest": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "http",
            "url": "http://127.0.0.1:65530/permission",
            "timeout": 600
          }
        ]
      }
    ]
  }
}
RAW_BUFFERClick to expand / collapse

Preflight Checklist

  • I have searched existing issues and this hasn't been reported
  • This is a single bug report
  • I am using the latest version of Claude Code (2.1.100)

What's Wrong?

When a PermissionRequest HTTP hook is registered but the endpoint is unreachable (e.g. ECONNREFUSED because nothing is listening on the port), Claude Code silently denies the tool call with this message:

The user doesn't want to proceed with this tool use. The tool use was rejected (eg. if it was a file edit, the new_string was NOT written to the file).

The user did not reject anything. No permission prompt is shown. No chat fall-through. The tool is silently denied because the hook server is offline.

This contradicts what the official documentation explicitly promises about HTTP hook failures.

What the documentation says

From https://code.claude.com/docs/en/hooks (HTTP hook fields):

Error handling differs from command hooks: non-2xx responses, connection failures, and timeouts all produce non-blocking errors that allow execution to continue. To block a tool call or deny a permission, return a 2xx response with a JSON body containing decision: "block" or a hookSpecificOutput with permissionDecision: "deny".

And specifically in the HTTP response handling section:

Connection failure or timeout: non-blocking error, execution continues

What Should Happen?

Per the docs, when the HTTP hook endpoint is unreachable, Claude Code should treat the failure as non-blocking and continue execution — i.e. fall through to whatever the default permission flow is (built-in chat prompt, applied permissions.allow rules, etc.). It should not silently reject the tool call as if the user had rejected it.

Steps to Reproduce

  1. Pick a high port that nothing is listening on. Verify with netstat -ano | findstr 65530 (Windows) or lsof -i :65530 (macOS/Linux) — should be empty.

  2. Add the following to ~/.claude/settings.json (back up your existing config first):

{
  "hooks": {
    "PermissionRequest": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "http",
            "url": "http://127.0.0.1:65530/permission",
            "timeout": 600
          }
        ]
      }
    ]
  }
}
  1. Open a new Claude Code session in any directory.

  2. Ask Claude to do something that needs permission, e.g. "Edit ./test.txt and write 'hello' to it".

  3. Observe: Claude reports "The user doesn't want to proceed with this tool use" immediately, with no permission UI shown.

Note on PermissionRequest matcher coverage

Per the docs, PermissionRequest matches on tool name with the same values as PreToolUse:

Matches on tool name, same values as PreToolUse.

This means a single misconfigured matcher: "" PermissionRequest HTTP hook with a dead endpoint blocks all permission-gated tools (Edit, Write, Bash, mcp__*, ...), not just Bash. This significantly amplifies the impact of the fail-closed behavior.

Is this a regression?

Unclear, and I cannot pin down the exact version that introduced it. What I can say:

  • The hook works correctly when the endpoint is reachable
  • I verified the documented "non-blocking on connection failure" behavior is in the public hooks docs as of today
  • Whether this is (a) a regression in failure handling or (b) a regression in matcher coverage (Edit/Write being newly routed through PermissionRequest), or (c) both — I would need a binary search across 2.1.x versions to be sure

Claude Code Version

2.1.100

Operating System

Windows 11 Pro for Workstations 10.0.26200

Terminal/Shell

Git Bash

extent analysis

TL;DR

The issue can be mitigated by ensuring the HTTP hook endpoint is reachable or by modifying the PermissionRequest hook configuration to handle connection failures as non-blocking errors.

Guidance

  • Verify that the HTTP hook endpoint is correctly configured and reachable by checking the port and URL specified in the ~/.claude/settings.json file.
  • Consider modifying the PermissionRequest hook configuration to include a fallback or default behavior for connection failures, as implied by the documentation.
  • Test the PermissionRequest hook with a reachable endpoint to confirm that it works correctly and that the issue is specific to connection failures.
  • Review the documentation for PermissionRequest and PreToolUse to ensure that the matcher coverage is correctly configured and understood.

Example

No code snippet is provided as the issue is related to configuration and behavior rather than code.

Notes

The root cause of the issue is unclear, and it is uncertain whether this is a regression or a configuration issue. Further investigation and testing are needed to determine the cause and develop a permanent fix.

Recommendation

Apply a workaround by modifying the PermissionRequest hook configuration to handle connection failures as non-blocking errors, as this is the behavior implied by the documentation. This will allow the tool to continue execution and fall back to the default permission flow when the HTTP hook endpoint is unreachable.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING