Bash tool prompts for approval despite matching allow-list rule + defaultMode: bypassPermissions

Status Open
Maintainer reply None cached
Activity 4 comments · opened Jul 20, 2026

Environment

  • Claude Code VSCode extension (native), Windows 10.
  • Project-level \.claude/settings.json\ with:
  • \permissions.defaultMode: \"bypassPermissions\"\
  • \permissions.allow\ including \\"Bash(*/python.exe -m pytest*)\"\ (plus other broad prefix-wildcard rules for git/gh/etc.)

Repro

Run, via the Bash tool, a command that matches an existing allow-list entry verbatim, e.g.:

\\\
pc_agent/.venv/Scripts/python.exe -m pytest pc_agent/tests/test_web.py -q
\
\\

Expected

No approval step at all - \defaultMode: \"bypassPermissions\"\ should skip prompting entirely, and this command also matches the explicit \allow\ rule independent of that.

Observed

The tool call required manual approval/was interceptable for denial rather than executing automatically. This has now been observed across multiple sessions in the same project, on multiple already-allow-listed command shapes (git checkout, gh issue create, plain ls, and this pytest invocation) - not a one-off.

One partial-recovery pattern was seen once: after editing \.claude/settings.json\ and starting a brand-new session, several subsequent commands executed cleanly without prompts (consistent with permission config only being read at session start, not hot-reloaded). But the same behavior recurred later within that same "recovered" session on a \python.exe\ invocation, so that isn't the full explanation either.

Questions for triage

  • Is \defaultMode\/\allow\ read once at session or tool-registration time? If so, is there a supported way to force a reload without a full restart?
  • Is there additional allow-list matching nuance (quoting, absolute vs relative path prefix, working-directory context) that could cause a rule that looks like it should match to silently not match?

Happy to provide the full \settings.json\ or more repro detail if useful.

View original on GitHub ↗

4 Comments

amirkedar · 1 month ago

Recurred again in the same session, same exact command, still rejected:

\\\
pc_agent/.venv/Scripts/python.exe -m pytest pc_agent/tests/test_web.py -q
\
\\

This is the third rejection of this identical allow-listed command in one session (defaultMode: bypassPermissions, and \Bash(*/python.exe -m pytest*)\ is in \permissions.allow\). Consistently reproducible on this specific command shape in this session - not a one-off.

amirkedar · 1 month ago

User-impact note, for prioritization context: this recurred 3x in a single session on an identical, already-allow-listed command (\Bash(*/python.exe -m pytest*)\ under \defaultMode: \"bypassPermissions\"\), after roughly 10 unrelated Bash/PowerShell calls earlier in the same session had gone through with zero prompts. The user described this as causing real, significant frustration/trust impact, not minor friction - repeated prompts on commands that should be silently allowed undermine the core value of setting bypassPermissions + an allow-list in the first place. Flagging the severity here in case it helps triage, separate from the technical repro above.

vincebowdrentribal · 1 month ago

Corroborating from a different surface (Claude Desktop, not the VSCode extension) — same signature: intermittent, session-scoped, not tied to a specific command shape.

Environment: Windows 11 Pro, Claude Desktop (entrypoint claude-desktop), Claude Code v2.1.215, project .claude/settings.json with defaultMode unset (default "default" mode, not bypassPermissions).

First occurrence (2026-07-22): Debugging why git -C <path> branch --show-current kept prompting despite a matching allow rule just added. Isolated by testing progressively broader commands in that same session: a bare git branch (exact-match rule), git log --oneline -1 (existing wildcard rule), and finally an unrelated, long-untouched pre-existing rule (cygpath -w ...). All of these required a manual click in that session — ruling out a glob-syntax bug in that specific edit; the allowlist wasn't being consulted at all for that session.

Second occurrence (2026-07-24), different session: A fresh session got a prompt for:

git -C /c/edgeteam/claude_wd/CustomerRelease/flux-k8s-terraform status --short
echo "--- current branch ---"
git -C /c/edgeteam/claude_wd/CustomerRelease/flux-k8s-terraform branch --show-current

despite matching wildcard rules already present in settings.json (Bash(git -C /c/edgeteam/claude_wd/*/* status *), Bash(git -C /c/edgeteam/claude_wd/*/* branch *), unchanged for 2+ days before this session started). The user approved it, which — per the "Always Allow saves dead rules" pattern noted elsewhere in this tracker — appended a new verbatim exact-match rule to settings.local.json rather than fixing anything.

Key point supporting "session-scoped, not command-shape-scoped": in a separate, concurrently-running session, the identical wildcard wcass (git -C <two-segment-repo-path> log -1, git -C <same path> branch -a — same repo, same */* glob shape, no pre-existing exact-match entry to fall back on) matched cleanly with zero prompts. Same settings.json on disk, same command shape, same day — one session honored the allow-list, another didn't. That rules out both "the glob syntax is wrong" and "this session started before the rule existed" as explanations; it looks like the allow-list is only sometimes being consulted per-session, independent of the rule or command itself.

This matches the reporter's "not a one-off, recurs across sessions on already-allow-listed shapes" framing, just via Desktop instead of the VSCode extension — suggesting the underlying cause is likely in a shared permission-matching component rather than something extension-specific.

squarestar · 1 month ago

Can confirm the same underlying issue, with a variant that may help narrow down root cause: the allow-list works correctly in the main session, but fails specifically for commands issued by a subagent (via the Agent/Task tool).

Environment: VS Code native extension, Windows 10, PowerShell primary shell

Project .claude/settings.json:

{
  "permissions": {
    "allow": [
      "Bash(git checkout *)",
      "Bash(git add *)"
    ]
  }
}

Repro:

  1. In the main session, run git add <file> — no prompt, matches the allow rule as expected.
  2. Dispatch a subagent (e.g. built-in general-purpose type) with a task that runs git add <file>.
  3. The subagent's identical git add call triggers a manual approval prompt, despite matching the same rule that just worked in step 1.

This suggests permission resolution for subagent-issued tool calls may not be consulting the same resolved rule set (project + global settings.json) that the main session uses — possibly consistent with the "read at session start vs. tool-registration time" question raised above, if subagents get their own tool-registration pass that doesn't inherit the parent session's already-resolved permission state.