[Bug] Excessive permission prompts for allowed directories in auto mode

Status Open
Reported on v2.1.258
Maintainer reply None cached
Activity 4 comments · opened Sep 2, 2026

Bug Description
permissions.blockReadsOutsideWorkingDirectories -- is being called with every single change, even when I have those directories enabled and allowed. So, I'm not sure but auto mode has me tapping approve again and again..

Environment Info

  • Platform: darwin
  • Terminal: iTerm.app
  • Version: 2.1.258
  • Feedback ID: ea2ce5ef-89c2-4390-9a3c-296086a9494b

Errors

[]

View original on GitHub ↗

3 Comments

TamasHamor · 1 month ago

I hit a related but distinct manifestation of blockReadsOutsideWorkingDirectories on Claude Code 2.1.259 (Windows 11) that might share a root cause with this issue, or might be worth splitting out:

Setup: permissions.defaultMode: "auto", permissions.blockReadsOutsideWorkingDirectories: true. A plugin installed from a directory-sourced marketplace entry (extraKnownMarketplaces) resolves its ${CLAUDE_PLUGIN_ROOT} to a path outside both the session's working directory and ~/.claude.

Symptom 1 — hard block, not a prompt: Every skill that reads its own bundled files via ${CLAUDE_PLUGIN_ROOT}/references/... or ${CLAUDE_PLUGIN_ROOT}/scripts/... gets an unconditional refusal from the Read tool — no approve/allow option, unlike the repeated-approval friction described above. Verbatim: "...is outside <cwd>; the permissions.blockReadsOutsideWorkingDirectories setting blocks reads outside the working directories. Ask the user to add the directory with /add-dir, or to remove that setting." Officially cached plugins under ~/.claude/plugins/cache/... are unaffected only because that path happens to already be reachable — there's no explicit exemption for plugin roots.

Symptom 2 — enforcement only covers the Read tool: The exact same absolute path that Read refuses is readable via Bash (cat, grep, sed all succeed unprompted). So the setting doesn't actually establish the confidentiality boundary it implies — it just breaks the Read tool for legitimate uses like plugin skills.

Introduced in ## 2.1.257: "Added a one-time prompt in auto mode before the first file read outside the working directories, with the option to block such reads (permissions.blockReadsOutsideWorkingDirectories)".

Filed as its own report (receipt dda5ba3a-d910-4635-92c4-d38fd4a44863) since the plugin-root and Read/Bash-asymmetry angles are distinct from the re-prompting behavior here, but flagging in case a maintainer wants to track them together.

jvegaEdiv · 1 month ago

Same regression on Linux (Ubuntu, kernel 6.8) / 2.1.259, with measurements and an A/B that isolates it to the binary version.

Setup: permissions.defaultMode: "auto", autoMode.allow: ["$defaults", ...], blockReadsOutsideWorkingDirectories not set. Permission config unchanged for weeks (project settings.local.json last modified in March; autoMode block in user settings since Aug 19).

Symptom: routine read-only Bash commands that auto-approved on 2.1.252 now hit a permission prompt. It is not rule-driven — identical command shapes get different outcomes — so it looks like the classifier / the new first-read-outside-cwd gate re-firing, not allow/deny matching.

Measured from the session transcript (tool_use → tool_result latency; Bash timeout is 120 s, so anything longer with is_error: false is time spent waiting on the prompt, not execution):

| where | command shape | wait |
|---|---|---|
| /code-review background fork | grep -rn "..." --include=*.pl --include=*.pm . (inside cwd) | 712 s |
| same fork | grep -rn ... . | 44 s / 31 s |
| same fork | grep -n ... file; echo ...; grep -rn ... . | 533 s |
| main session | python3 - <<EOF reading ~/.claude/projects/... | ~390 s ×3 |
| main session | identical grep -rn ... . a few minutes later | 4 s (auto-approved) |

The other 12 of 16 tool calls in the fork (git diff, sed -n, grep -n <file>) returned in 0.1 s. Net effect: a /code-review run took 26 min, 21 of which were the background agent blocked on prompts that surface only in the parent session — so the user does not see them until they come back to the parent (related: #87994).

A/B: DISABLE_AUTOUPDATER=1 + relink ~/.local/bin/claude → versions/2.1.252, resume the same session. Re-ran the same command shapes (recursive grep in cwd, sed -n on ~/.claude/settings.json, gh pr view, git diff, a container tail wrapper): 0 prompts in 8 calls, all ≤ 2.7 s. On 2.1.259 the same session had prompted on ~3 of every 20 main-session calls.

Two side notes for whoever picks this up:

  • autoUpdates: false in settings.json did not stop the updater on 2.1.252: on the next launch it relinked to 2.1.259 (.last-update-result.json: version_from 2.1.252 → version_to 2.1.259). Only DISABLE_AUTOUPDATER=1 held the pin.
  • The auto_mode attachment in the affected transcript reads {"autoModeConsentFlow":false,"bashFirst":true,"steerOnly":true,"bypass":false} — bashFirst steers the model to grep -rn/cat via Bash instead of the Grep/Read tools, which is exactly the surface that now prompts.

Happy to share redacted transcript excerpts (timestamps + tool ids) if useful.

jvegaEdiv · 1 month ago

Confirmed fixed on 2.1.260 (Linux, permissions.defaultMode: "auto").

The 2.1.260 changelog entry names the mechanism: "Reverted the 2.1.259 change applying Read() deny rules to Bash arguments; ... made cd … && grep prompt even in auto mode". That matches the evidence in my earlier comment precisely — my deny list contains Read(.env) / Read(.env.*), so every grep -rn … . (the . reaches .env) and every cd … && grep was gated, while greps naming explicit files, sed -n and git diff stayed at 0.1 s. It was the deny matcher over Bash args, not the auto-mode classifier as I first suspected.

Re-ran the same 5-command smoke set on 2.1.260: no prompts, all calls sub-3s. Promoted it as our pinned version.

Note this is a distinct root cause from the blockReadsOutsideWorkingDirectories reports in this thread (the OP's macOS re-prompting and the Windows plugin-root block), which 2.1.260 addresses separately and only for macOS. Worth keeping the issue open for those.

Showing cached comments. Read the full discussion on GitHub ↗