[BUG] VS Code extension 2.1.259: Bash permission prompts fire despite bypassPermissions mode and a bare `Bash` allow rule
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Summary
After the VS Code extension self-updated to 2.1.259, Bash permission prompts
("Allow this bash command?") began appearing in sessions running inbypassPermissions mode that also have a bare Bash allow rule loaded. Either
condition alone should make a Bash prompt impossible. Prompts did not occur on the
previous version with identical settings. The behaviour is intermittent and
survives a full VS Code restart.
Environment
- VS Code extension: 2.1.259 (bundled native binary,
BUILD_TIME 2026-09-02T18:43:49Z) - Standalone CLI on PATH: 2.1.231 — unaffected; the issue appears only in the extension panel
- Linux,
installMethod: native - No managed settings (
/etc/claude-code/absent), nosettings.local.json - Session cwd is the user's home directory, so
~/.claude/settings.jsonresolves as
both userSettings and projectSettings
The extension launches the binary with:
--permission-mode bypassPermissions --allow-dangerously-skip-permissions
--permission-prompt-tool stdio --setting-sources=user,project,local
--debug --debug-to-stderr
Relevant user settings:
{
"permissions": {
"defaultMode": "bypassPermissions",
"allow": ["Bash", "..."],
"deny": ["Read(...)", "..."]
},
"skipDangerousModePermissionPrompt": true
}
Expected
No Bash permission prompt. Mode is bypassPermissions, and a bare Bash allow
rule matches every Bash invocation.
Actual
Prompts appear for ordinary read-only commands, e.g.:
Allow this bash command?
cd ~/PROJECT && git diff --cached -- a.md b.md c.md
Read staged diff to author commit summary
1 Yes
2 No
Note this instance offers only Yes/No — no "allow for this project" option.
Other prompts in the same session do offer the third option and decompose the
command into per-subcommand rule suggestions. Unclear what drives the difference.
Evidence from --debug output
Mode is active at the time prompts occur:
[DEBUG] [session-notices] advertise=false mode=bypassPermissions flag=false(fallback)
pollChannel=false remote=false remoteEnv=false nonInteract...
Rules load correctly into both sources, with bare Bash first in the allow list:
Replacing all allow rules for destination 'userSettings' with 76 rule(s): ["Bash", ...]
Replacing all deny rules for destination 'userSettings' with 13 rule(s): [...]
Replacing all allow rules for destination 'projectSettings' with 76 rule(s): ["Bash", ...]
Replacing all ask rules for destination 'userSettings' with 0 rule(s): []
The extension then records the prompt being answered:
Received message from webview: {"type":"response","response":{"type":
"tool_permission_response","result":{"behavior":"allow","updatedInput":{...},
"updatedPermissions":[]}}}
Ruled out
- Ask rules — the
askrule set is empty in every source (logged above). - Deny rules — 13 present, all
Read(...)on secret paths plus four
Bash(cat ...) on key directories; none match the prompted commands.
- PreToolUse hooks — five Bash hooks registered; all emit only
permissionDecision: "deny" or exit 0. None can produce an "ask".
- Sandboxing — not engaged.
IS_SANDBOXunset, nobwrapin the Bash process
ancestry, no sandbox config in settings.
cdin compound commands — tested directly.git -C DIR diff --cached --stat
and cd DIR && git diff --cached --stat both ran with no prompt, so the leading
cd present in every observed prompt is coincidental, not causal.
- Trust —
hasTrustDialogAcceptedwas toggled true and back to false for the
session's directory; no effect either way.
- Rule-set reload race — settings reload is implemented as clear-then-set
(with 0 rule(s): [] immediately followed by with 76 rule(s)). Measured
windows are 2–6 ms and observed prompts do not fall inside one, so this looks
like a red herring — flagging it in case the cleared state is observable elsewhere.
Possibly related, lower priority
Two new rule-lint warnings surfaced by this version. Both are correct and were
useful — no complaint, just noting they are new:
[permissions] Permission allow rule (.claude/settings.json): Write(/home/USER/.claude/**)
is not matched by file permission checks — only Edit(path) rules are. Use Edit(...)
[permissions] Permission allow rule (.claude/settings.json): Bash(rm -rf * .git)
has a wildcard before the rest of the command, so it also matches any options
inserted at...
Notes
I could not find a decision reason logged at the moment a prompt is raised — the
extension log captures only the webview's response, not the CLI's rationale. If
there is a flag that logs the permission-decision path for Bash, I'm happy to
capture it and add the output here.
What Should Happen?
No prompts
Error Messages/Logs
Steps to Reproduce
Steps to reproduce
I cannot reproduce this on demand. It is intermittent — roughly 28 prompts across
~90 minutes of ordinary use in three concurrent sessions. What I can give is the
exact environment plus a list of candidate triggers I tested and eliminated, so
nobody re-treads them.
Setup
- Linux, VS Code with the Claude Code extension at 2.1.259,
installMethod: native. ~/.claude/settings.jsonwith:
``json``
{
"permissions": {
"defaultMode": "bypassPermissions",
"allow": ["Bash", "... ~70 more specific rules ..."],
"deny": ["Read(...)", "..."]
},
"skipDangerousModePermissionPrompt": true
}
- Open the panel with the session cwd set to the user's home directory, so
~/.claude/settings.json resolves as both userSettings and projectSettings.
- Confirm the mode indicator shows Bypass Permissions is on.
- Use the session normally — reading files, running
git,grep,wc,cp.
Prompts appear for a minority of Bash calls, with no pattern I could isolate.
Does NOT reproduce it (each tested directly in a live bypass-mode session,
with the extension log checked afterwards to confirm no prompt was raised):
| candidate | result |
|---|---|
| cd in a compound command | no prompt |
| cd plus a relative path that only resolves after the cd | no prompt |
| absolute path, no cd | no prompt |
| tilde-prefixed vs fully-qualified paths | no difference observed |
Possible lead. Prompts appear to be self-limiting: choosing "allow for this
project" adds a specific Bash(<command>) rule, and that command shape does not
prompt again — the allow list grew from 65 to 76 entries over the session purely
from those clicks. That suggests specific Bash(...) rules are consulted while
the bare Bash rule is not. However, unrelated read-only commands
(wc, grep, git diff --stat) never prompted despite having no matching
specific rule, which may mean they are being cleared by a read-only classifier
rather than by the bare Bash rule — so the bare rule's effectiveness is
untested either way.
Notably, cd ~/REPO && git diff --cached -- a.md b.md c.md did prompt, whilecd /home/USER/REPO && git diff --cached --stat did not. Both are read-onlygit diff invocations in the same repository. If the read-only classifier is
involved, the difference between those two is where I would look first.
What would nail it. A debug flag that logs the permission-decision path anddecisionReason for each Bash call. The extension log records only the webview'stool_permission_response, never the CLI's rationale for raising the prompt, so
from outside there is no way to see which check fired. I have a PreToolUse hook
logging every Bash invocation now, and can diff all-commands against
prompted-commands the next time one fires — happy to attach that.
Claude Model
Not sure / Multiple models
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
2.1.259
Platform
Anthropic API
Operating System
Ubuntu/Debian Linux
Terminal/Shell
Other
Additional Information
_No response_
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗