[BUG] permission prompts persist (and worsen) despite bypassPermissions + skipDangerousModePermissionPrompt being explicitly set — likely same root cause as #72903, opposite symptom

Status Open
Maintainer reply ✓ Yes — bcherny
Activity 3 comments · opened Jul 30, 2026
💡 Likely answer: A maintainer (bcherny, collaborator) responded on this thread — see the highlighted reply below.

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?

Permission prompts for tool calls (Bash, Edit, Write) keep appearing and getting more frequent over time, despite explicitly configuring the project to skip all prompts. I set permissions.defaultMode: "bypassPermissions" and skipDangerousModePermissionPrompt: true in .claude/settings.local.json, verified the JSON is valid and not overridden by any other settings file (no project settings.json, no conflicting user-level or managed settings, no "ask"/"deny" rules). Prompts still appear, and each approved prompt gets appended to permissions.allow as a new ultra-narrow, near-exact-match rule instead of being suppressed by bypass mode. This persisted across a full new session/window restart, so it isn't a stale-config/hot-reload issue.

Likely related to https://github.com/anthropics/claude-code/issues/72903, which reports the opposite symptom (no prompts ever appear, even without bypass mode) citing the same cached feature flags.

What Should Happen?

With permissions.defaultMode set to "bypassPermissions" and skipDangerousModePermissionPrompt set to true, no tool permission prompts should appear at all for this project (only AskUserQuestion should ever require interaction).

Error Messages/Logs

Steps to Reproduce

  1. In a project's .claude/settings.local.json, set:

{
"permissions": {
"allow": [],
"defaultMode": "bypassPermissions"
},
"skipDangerousModePermissionPrompt": true
}

  1. Start a new Claude Code session/window in that project.
  2. Ask Claude to run any Bash command (e.g. git status, docker ps).
  3. A permission prompt appears anyway.
  4. Approve it — observe that a new narrow allow rule (e.g. "Bash(docker ps)") gets appended to settings.local.json instead of bypass mode taking over.
  5. Repeat with a different command — a new prompt appears again, and another narrow rule gets appended. The list grows; prompts never converge to zero.

Note: inspecting ~/.claude.json → cachedGrowthBookFeatures shows:
"tengu_permission_friction": true
"tengu_cfc_in_product_permissions": true
"tengu_disable_bypass_permissions_mode": false

Claude Model

Sonnet (default)

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

26.721.41059

Platform

Anthropic API

Operating System

Ubuntu/Debian Linux

Terminal/Shell

VS Code integrated terminal

Additional Information

Related issue: https://github.com/anthropics/claude-code/issues/72903 — reports the opposite symptom (no permission prompts ever appear) citing the same feature-flag set: tengu_permission_friction, tengu_cfc_in_product_permissions, tengu_harbor_permissions, tengu_disable_bypass_permissions_mode. Given the overlap, this looks like a broader instability in how these flags are evaluated/cached per account, manifesting as either "no prompts ever" or "prompts that never stop and keep multiplying," rather than two unrelated bugs.

View original on GitHub ↗

3 Comments

bcherny collaborator · 14 days ago

Thanks for the detailed report. I tried to reproduce this on the released CLI 2.1.233 (macOS): fresh project, .claude/settings.local.json set exactly as in your steps (defaultMode: "bypassPermissions", skipDangerousModePermissionPrompt: true), started claude in the terminal. The session came up with "bypass permissions on" in the footer, and running git status, docker ps, creating a file, and editing a file all executed with no permission prompts and nothing was appended to settings.local.json.

One thing that stands out: the version you listed (26.721.41059) isn't a CLI version, and you mention starting a new "session/window" in VS Code. If you're using the Claude Code VS Code extension (the panel/chat UI, not claude typed into the terminal), this is expected: the extension does not read a project's .claude/settings.json or .claude/settings.local.json for the starting permission mode. To start extension conversations in bypass mode, enable Allow dangerously skip permissions in the extension settings and set claudeCode.initialPermissionMode to bypassPermissions in your VS Code user settings (or pick it from the mode indicator). Docs: https://code.claude.com/docs/en/permission-modes#switch-permission-modes and https://code.claude.com/docs/en/vs-code. Note skipDangerousModePermissionPrompt only skips the one-time confirmation dialog; it doesn't turn bypass mode on by itself. Approved prompts adding narrow Bash(...) rules is the normal "don't ask again" behavior when a session is in the default (Manual) mode.

If you are running claude in the integrated terminal, could you share the output of claude --version and claude doctor, plus what the footer shows at startup ("bypass permissions on" vs. nothing)? That would tell us whether something else is overriding the mode.

🤖 Generated with Claude Code

MrRosc · 14 days ago

Thank... yes, I was using the Claude Code VS Code extension, not the CLI in the integrated terminal.

So the version I reported was the extension version, which explains why it did not match the CLI version format.

I had permissions.defaultMode: "bypassPermissions" and skipDangerousModePermissionPrompt: true in the project .claude/settings.local.json, but I did not separately set claudeCode.initialPermissionMode to bypassPermissions in the VS Code user settings.

That likely explains the behavior I was seeing. Thanks for clarifying the distinction between the CLI and the VS Code extension permission settings.

TubbyChill · 3 days ago

Confirming same symptom on a different setup — CLI 2.1.119, not the VS Code extension. Wanted to add a Linux/native-CLI datapoint alongside the OP's VS-Code report and bcherny's macOS 2.1.233 non-repro, in case it helps triangulate whether the fix is version-gated (in which case 2.1.233 users are safe) or config-gated (in which case 2.1.233 needs to test with a "grown" allow list too).

Environment

| Field | Value |
|---|---|
| Claude Code CLI | 2.1.119 (via nvm-managed ~/.nvm/versions/node/v22.22.0/bin/claude) |
| OS | Ubuntu on WSL2 (Linux 6.6.87.2-microsoft-standard-WSL2) · Windows host |
| Shell | zsh (/usr/bin/zsh) |
| Startup | claude --dangerously-skip-permissions (three concurrent sessions in the same repo) |
| Model | opus[1m] · alwaysThinkingEnabled: true · effortLevel: xhigh |
| Repo | large monorepo (multi-app WordPress SaaS) |

Bug reproduces even though all three of these are already set:

  • ~/.claude/settings.jsonpermissions.defaultMode: "bypassPermissions" + skipDangerousModePermissionPrompt: true at top level
  • Project .claude/settings.local.json → same two flags
  • CLI flag --dangerously-skip-permissions on every claude process

Trigger (matches OP exactly)

An agent-generated Bash tool call bundling common git operations:

git branch --show-current
git log --oneline -3
for i in 1 2 3 4; do [ ! -f .git/index.lock ] && break; sleep 3; done
[ -f .git/index.lock ] && rm -f .git/index.lock
git pull origin master 2>&1 | tail -3

TUI prompt appears anyway:

Bash command
  git branch --show-current
  git log --oneline -3
  for i in 1 2 3 4; do [ ! -f .git/index.lock ] && break; sleep 3; done
  [ -f .git/index.lock ] && rm -f .git/index.lock
  git pull origin master 2>&1 | tail -3

Do you want to proceed?
❯ 1. Yes
  2. Yes, and always allow access to .git/ from this project
  3. No

Interesting wrinkle in the wording: option 2 is specifically about .git/ directory access, not about the Bash tool. So the prompt seems to be gating on a filesystem-region permission (the compound git/rm .git/index.lock/git pull command touches .git/), and the bypass mode is not covering that specific gate. This is a subtle-but-distinct axis from "Bash tool prompt" and might be why 2.1.233's Bash-focused test does not reproduce.

Symptom that matches the OP's "prompts multiply"

Our project .claude/settings.local.json.allow had ~30 rules grown by repeated "Yes and always allow" acceptances over months — many were ultra-narrow patterns for very specific one-shot commit messages (Bash(git commit -m 'fix\\(#15188\\): trapac fixture v2 · exact-screenshot config ... *)). Textbook "never converges to zero" pattern.

What we tried on 2.1.119 (belt-and-braces)

Rewrote both settings files this session:

User-level ~/.claude/settings.json — added broad prefix rules so per-project narrow rules stop being appended:

"permissions": {
  "allow": [
    "Read", "Edit", "Write",
    "Bash(git *)", "Bash(gh *)", "Bash(rm -f *.lock)",
    "Bash(rm -f .git/index.lock)",
    "Bash(rsync *)", "Bash(ssh *)", "Bash(scp *)",
    "Bash(curl *)", "Bash(bash *)", "Bash(php *)",
    "Bash(node *)", "Bash(npm *)", "Bash(yarn *)",
    "Read(.git/**)", "Edit(.claude/**)"
  ],
  "deny": [
    "Bash(git push --force origin master)",
    "Bash(git push --force origin main)",
    "Bash(rm -rf /)", "Bash(rm -rf /*)"
  ],
  "defaultMode": "bypassPermissions",
  "additionalDirectories": [".git"]     // ← explicit .git allowance for the "always allow access to .git/" prompt
},
"skipDangerousModePermissionPrompt": true

Project .claude/settings.local.json — collapsed the sprawled 30-rule allow array down to 7 essentials + the additionalDirectories: [".git"] addition + same top-level flag.

Both files pass jq empty (valid JSON). Both have defaultMode: bypassPermissions inside permissions AND skipDangerousModePermissionPrompt: true at the top level, per the schema. We'll observe over the next few work sessions whether this stops the prompts on 2.1.119; if it does not, we will upgrade to ≥ 2.1.233 and re-verify.

Suggestions

  1. Document the .git/ directory-access prompt as a separate gate. The OP + bcherny thread reads as if the whole class of prompts is Bash tool gating, but this specific "always allow access to .git/" prompt is filesystem-scope. If the 2.1.233 fix is bypass-mode-for-Bash-only, users touching .git/ would still see this variant.
  2. Consider a one-shot "collapse narrow allow rules" command — most affected users end up with dozens of ultra-narrow rules that could be safely subsumed by a broader Bash(git *). A claude config collapse-allow would let users clean up without editing JSON by hand.
  3. Confirm behaviour on --dangerously-skip-permissions CLI flag independently — I would expect the CLI flag to be an even stronger override than the settings.json equivalent, but our reproduction has the flag active on all three processes and still sees the prompt.

Happy to re-test with 2.1.233 and post again if it helps confirm the fix is version-gated.

— Sergey (olivier@dmslog.ai · reporter on behalf of DMSLOG)