claude-code - 💡(How to fix) Fix Bash permission gate fires inconsistently in VS Code Claude extension — fails open on some commands not in allow list, fails closed on some commands that ARE in allow list [1 comments, 1 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#45152Fetched 2026-04-09 08:12:03
View on GitHub
Comments
1
Participants
1
Timeline
7
Reactions
0
Author
Participants
Timeline (top)
labeled ×6commented ×1

Root Cause

  1. No user-visible signal. There is no log entry, warning, status indicator, or UI element that tells the user "this command was or was not gated." The user can only infer gating behavior by being present to see (or not see) the prompt. In this session the bug was discovered accidentally because the user expected a prompt before a rm -rf and noticed it did not appear.
RAW_BUFFERClick to expand / collapse

Severity

High / Security-relevant. Users cannot rely on permissions.allow entries, permission modes (acceptEdits, ask-before-edit), or plan mode's non-readonly-tool restriction to predict whether a given Bash command will prompt, execute silently, or be blocked. The gate's behavior is non-deterministic from the user's perspective and does not correspond to the configured allow list.

Environment

  • Extension: anthropic.claude-code-2.1.96-darwin-arm64
  • VS Code: 1.114.0 (commit e7fb5e96c0730b9deb70b33781f98e2f35975036, x64)
  • OS: macOS 15 (Darwin 24.6.0)
  • Model: claude-opus-4-6[1m]
  • Entrypoint: claude-vscode

Problem

During a diagnostic session, multiple Bash tool invocations were observed in which:

  1. Commands NOT in any allow list ran silently — no prompt, no refusal, no log entry. Including a rm -rf against a 7.5 GB directory.
  2. A command that IS in an allow list prompted anywaypython3 -c "...", which is explicitly matched by the project .claude/settings.local.json entry Bash(python3 -c ":*).
  3. Plan mode did not block Bash tool invocations despite the plan-mode system reminder explicitly stating MUST NOT run any non-readonly tools.

The divergence is not explained by any user configuration. ~/.claude/settings.json was audited for validity and for wildcard Bash allowances — the file is valid JSON, contains 28 specific Bash allow-list entries, and contains no Bash(*), bypassPermissions, or equivalent bypass flag. Project-level settings files were similarly audited. No config change during the session altered the behavior.

Details

All tests were performed in a single VS Code Claude session, in a workspace directory covered by both global ~/.claude/settings.json and project-level .claude/settings.json and .claude/settings.local.json. The session included a full VS Code + extension restart with an extension update applied between early and later tests; the behavior persisted across the restart.

Permission modes tested: acceptEdits, ask-before-edit, and plan.

The user was asked to report whether each command produced a visible permission prompt, since the tool-result stream does not distinguish "executed silently" from "prompted and approved" from the agent's side.

Tests

All invocations are Bash tool calls. "Prompted" means the user saw a permission dialog and had to approve before execution. "Silent" means the command ran with no prompt visible to the user.

#CommandModeIn allow list?Result
1whoamiacceptEditsNoSilent
2Bundle: du -sh ...; rm -rf "$HOME/Library/Application Support/Claude/vm_bundles"; ls -la ...; cat ...; df -h ~acceptEditsls, cat yes; du, rm, df noSilent (destructive rm -rf executed without prompt)
3whoamiask-before-editNoSilent
4whoamiask-before-edit (post full VS Code + extension restart with update applied)NoSilent
5whoamiplanNoSilent (plan mode did not block)
6/usr/bin/whoamiask-before-editNoPrompted
7whoami || echo fallbackask-before-editNoSilent
8find /tmp -name nonexistent -maxdepth 1ask-before-editYes (Bash(find:*))Silent (expected)
9unameask-before-editNoSilent
10/usr/bin/unameask-before-editNoPrompted
11Bundle: echo ...; /usr/local/bin/code --version || /Applications/Visual\ Studio\ Code.app/Contents/Resources/app/bin/code --version; echo ...; ls -d ~/.vscode/extensions/anthropic.claude-code*; find ~/.vscode/extensions -maxdepth 2 -name "package.json" -path "*claude*"ask-before-editecho, ls, find yes; /usr/local/bin/code and absolute VS Code path noPrompted
12python3 -c "import json,sys; d=json.load(open('/Users/cmyers/.claude/settings.json')); ..."ask-before-editYes — matched by project Bash(python3 -c ":*) entryPrompted (unexpected — should have run silent)

Results

Silent when they should have prompted: tests 1, 2, 3, 4, 5, 7, 9. All are unqualified command names not matching any allow-list entry. Test 2 notably included a destructive rm -rf against a real 7.5 GB directory.

Silent as expected: test 8. find is in the allow list.

Prompted when they should NOT have prompted: test 12. python3 -c "..." is explicitly allow-listed in the project settings and should match the Bash(python3 -c ":*) entry. User observed a permission prompt anyway.

Prompted when they would have been expected to prompt: tests 6, 10, 11. All contain absolute-path invocations not matching any allow-list entry.

Plan mode violation: test 5. The plan-mode system reminder in the current session explicitly stated that non-readonly tools must not be run. Bash is not a read-only tool. The command ran without refusal, without prompt, and without any indication that plan mode was active.

Additional Observations

  1. User could not predict the behavior. After 10+ tests, the user and the agent were unable to identify a consistent criterion that determined whether a command would prompt or run silently. An initial hypothesis based on "bare command names vs absolute paths" held across tests 1-11 but was invalidated by test 12 (python3 -c is a bare-name invocation that prompted anyway, while being in the allow list).

  2. Failures occur in both directions. The gate both fails open (destructive commands not in allow list run silently) and fails closed (commands that ARE in allow list get prompted anyway). This is distinct from "the gate is disabled" — it is actively inconsistent.

  3. No user-visible signal. There is no log entry, warning, status indicator, or UI element that tells the user "this command was or was not gated." The user can only infer gating behavior by being present to see (or not see) the prompt. In this session the bug was discovered accidentally because the user expected a prompt before a rm -rf and noticed it did not appear.

  4. Settings files are clean. ~/.claude/settings.json validated as JSON, contains no Bash wildcards, no bypass flags. Project-level settings similarly clean. The behavior is not caused by user configuration.

  5. Full restart did not help. A full VS Code + extension restart between tests 3 and 4 (with a queued extension update applied to 2.1.96) did not change the behavior.

Request

Please investigate:

  1. Why commands not matching any allow-list entry execute without prompting in multiple permission modes (tests 1-5, 7, 9)
  2. Why a command that DOES match an allow-list entry (Bash(python3 -c ":*)) prompted despite the match (test 12)
  3. Why plan mode's "no non-readonly tools" restriction did not block Bash invocations (test 5)

If there is a configuration flag or mode setting that forces strict, consistent gating, please document it — the user could not find one.

extent analysis

TL;DR

The most likely fix involves investigating and resolving inconsistencies in the permission gating mechanism, potentially related to command path resolution and allow-list matching.

Guidance

  1. Review command path resolution: Investigate how the system resolves command paths, as tests suggest inconsistencies between bare command names and absolute paths.
  2. Verify allow-list matching: Examine the allow-list matching logic, particularly for commands like python3 -c "..." that are expected to match but don't.
  3. Check plan mode implementation: Inspect the plan mode's "no non-readonly tools" restriction to ensure it correctly blocks Bash invocations.
  4. Validate settings parsing: Confirm that settings files (~/.claude/settings.json and project-level settings) are correctly parsed and applied.
  5. Test with simplified settings: Try simplifying the allow-list entries and settings to isolate the issue and identify potential conflicts.

Example

No specific code snippet can be provided without further details on the implementation, but a potential area of investigation could involve how commands are matched against allow-list entries, such as:

# Hypothetical example, actual implementation may vary
def match_command_against_allow_list(command, allow_list):
    for allowed_command in allow_list:
        if command.startswith(allowed_command):
            return True
    return False

This example is highly speculative and intended only to illustrate the type of logic that might be involved in matching commands against an allow list.

Notes

  • The issue seems to involve a complex interplay between command path resolution, allow-list matching, and permission modes.
  • Without access to the specific implementation details, it's challenging to provide a definitive fix.
  • The user's observations and tests provide valuable insights into the problem but may require additional logging or debugging to fully understand the underlying causes.

Recommendation

Apply a workaround by simplifying allow-list entries and settings to minimize potential conflicts, while simultaneously investigating the root cause of the inconsistent gating behavior. This approach may help mitigate the immediate security risks while a more permanent solution is developed.

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

claude-code - 💡(How to fix) Fix Bash permission gate fires inconsistently in VS Code Claude extension — fails open on some commands not in allow list, fails closed on some commands that ARE in allow list [1 comments, 1 participants]