Repository navigation
[BUG] v2.1.78: Protected directory prompt in bypassPermissions has no override — forces hacky workarounds #35646
Description
Activity
- addedbugSomething isn't workingSomething isn't workingplatform:linuxIssue specifically occurs on LinuxIssue specifically occurs on Linuxhas reproHas detailed reproduction stepsHas detailed reproduction steps
on Mar 18, 2026 i found this problem minutes ago too! This break my daily workflow as well.
Reacted by interconnectedMeI already filed a duplicate issue
Reacted by interconnectedMecruppertautomation-ai commented
on Mar 18, 2026 AuthorMore actionsBut why, I was earlier :-) But i dont mind which we keep open... (though yes, you did file a duplicate, did your Claude not do a proper search or did mine select a shitty title?)
- marked [BUG] Claude code asking for permission to edit its own settings when bypass permissions is enabled #35808 as a duplicate of this issue
on Mar 18, 2026 matthew-plusprogramming commented
on Mar 18, 2026 More actions+1
But why, I was earlier :-) But i dont mind which we keep open... (though yes, you did file a duplicate, did your Claude not do a proper search or did mine select a shitty title?)
The former I suppose, I already fired my agent
I hesitate to share it, in case it get "patched", but maybe they'll fix this mess if they work this issue: symlinks seem to be safe, so if you symlink the skills folder, or even all of .claude, it seems to work.
Hard to believe this was the intended behavior. I expected to pop in and find a bug report and it turns out this is the "fix"! I've had agents working on optimizing our claude code structure for months now.
This is driving me insane approving individual edits whenever claude code is writing or updating skills in
~/.claude/skillsClick fatigue destroys security
Very true, and is how you end up with people running fully permissive openclaws everywhere 😅
Reacted by MelonCholi and Jamie Clayton- marked [BUG] --dangerously-skip-permissions does not bypass "modify config files" prompt for ~/.claude/ writes #35718 as a duplicate of this issue
on Mar 20, 2026 Fix incoming
Reacted by Jordan Parker, Emmanuel Galanos, OrdenDelfai, bpatterson-slx, Dhruv Anand, Sam, JaeHo Song and Will DelHagen5 remaining items
I'm having this issue on verision 2.1.81, on Mac
Reacted by Will DelHagencruppertautomation-ai commented
on Mar 23, 2026 AuthorMore actionsJust FYI - I think the "fix incoming" was after release of 2.1.81 - i jumped back to .66 and waiting for 82 until i try again. Just for all trying in 81 - think this will be earliest in 82 (just guessing though, but timeline does not fit an include in 81 according to my Claude) - also do not see it here, so i assume really gotta wait for 82:
https://github.com/anthropics/claude-code/blob/main/CHANGELOG.md
Just FYI - I think the "fix incoming" was after release of 2.1.81 - i jumped back to .66 and waiting for 82 until i try again. Just for all trying in 81 - think this will be earliest in 82 (just guessing though, but timeline does not fit an include in 81 according to my Claude) - also do not see it here, so i assume really gotta wait for 82:
https://github.com/anthropics/claude-code/blob/main/CHANGELOG.md
Thanks @cruppertautomation-ai I'm already a few hours into trying to debug my setup and this saved me from going deeper down that rabbit hole.
Sharing my temporary workaround until the fix ships
Still hitting this on 2.1.81. I needed writes to
~/.claude/skills/and.claude/skills/(project-level) to go through without prompting for slash commands that write skill/report files. Sharing in case it's useful. Happy to hear if there's a better approach or if I'm missing edge cases.The workaround is a
PermissionRequesthook that auto-approves reads and writes to the three exempt subdirectories.Add to any settings file (
~/.claude/settings.json,.claude/settings.json, or.claude/settings.local.json). Merge into existinghooksif you already have hooks configured:{ "hooks": { "PermissionRequest": [ { "matcher": "Read|Edit|Write", "hooks": [ { "type": "command", "command": "bash -c 'if sed -n \"s/.*\\\"file_path\\\":[[:space:]]*\\\"\\([^\\\"]*\\)\\\".*/\\1/p\" | grep -qE \"^($HOME/\\.claude|\\.claude)/(skills|commands|agents)/\"; then echo \"{\\\"hookSpecificOutput\\\":{\\\"hookEventName\\\":\\\"PermissionRequest\\\",\\\"decision\\\":{\\\"behavior\\\":\\\"allow\\\"}}}\"; fi'" } ] } ] } }Uses
sedandgrepto keep dependencies minimal. These are available on macOS, Linux, and Windows via Git Bash (which Claude Code uses internally on Windows). If you havejq, you can replace thesedextraction withjq -r ".tool_input.file_path // empty"for more robust JSON parsing.How it works: The hook fires when the protected directory prompt is about to appear. It extracts
tool_input.file_pathfrom the hook input and checks whether it starts with$HOME/.claude/skills/,commands/, oragents/(global) or.claude/skills/,commands/, oragents/(project-level). If matched, it returns an allow decision and the prompt is skipped. Other.claude/paths (e.g.,settings.json) still trigger the normal prompt.Lightly tested with Read, Write, and Edit tools on Linux (
bypassPermissionsmode) and macOS (acceptEditsmode). Not tested on Windows, but Claude Code uses Git Bash internally there, sobash/sed/grep/$HOMEshould be available.Reacted by Patryk Krzyzanskicruppertautomation-ai commented
on Mar 24, 2026 AuthorMore actionsNice one, i have a way bigger hook system in place anyway, but i was missing that hook. One possibly important note (though its unverified and I am to lazy to look into it - I had behaviour when hitting the permission prompt (and approving it) that it was loosing the "dangerously skip" flag completely - falling back to asking for every tool call. I think in that case even the "approve for this session" broke. Might have been side effect of my setup, or some ugly gotcha... Again, just FYI, but I guess with the above hooks its still possible to mitigate. I mean I could even write my own "dangerous" by simply approving all.
For anybody (like me) who missed a few hooks which came "recently" here is a list my Claude just compiled - after he realized there are way more hooks than he though there are:
- v2.0.45+ (Nov 2025 - Early 2026) — PreToolUse, PostToolUse, UserPromptSubmit, Notification, Stop, SubagentStart, SubagentStop, PermissionRequest
- v2.1.47 (Feb 18) — SessionStart
- v2.1.49 (Feb 19) — ConfigChange
- v2.1.50 (Feb 20) — WorktreeCreate, WorktreeRemove
- v2.1.63 (~Mar 1) — HTTP hook type added
- v2.1.69 (Mar 5) — InstructionsLoaded
- v2.1.72 (Mar 10) — TeammateIdle, TaskCompleted
- v2.1.76 (Mar 14) — PreCompact, PostCompact, Elicitation, ElicitationResult
- v2.1.78 (Mar 17) — StopFailure, SessionEnd
PS: HTTP hooks are neat, removes overhead of python call, gets timing down to MS - you can have one persistant service containing all the logic which is ready when hook fires and answers fast, got a few rust ones for that.. (we did switch to that pattern a while back, but I forgot to force him to look up full available hook list)
Still broken on v2.1.83 (macOS) — protected-dir check short-circuits before PermissionRequest hooks in
-pmodeVersion: 2.1.83
OS: macOS (Darwin 25.3.0)Finding
The protected-dir check in
claude -pmode never fires a PermissionRequest event, so the hook workaround shared by @wdelhagen cannot work for non-interactive subprocess invocations.Evidence from stream-json output
The model does call the Write tool. The harness intercepts it and returns an error directly — no PermissionRequest event is generated:
// Model calls Write {"type":"assistant","content":[{"type":"tool_use","name":"Write","input":{"file_path":"/Users/.../.claude/.tmp/test.txt","content":"hello"}}]} // Harness returns error directly (no PermissionRequest, no hook fired) {"type":"user","content":[{"type":"tool_result","content":"Claude requested permissions to edit .../.claude/.tmp/test.txt which is a sensitive file.","is_error":true}]} // Final result includes permission_denials {"type":"result","permission_denials":[{"tool_name":"Write","file_path":".../.claude/.tmp/test.txt"}]}
Verification
A
PermissionRequesthook with debug logging (echo "$INPUT" >> /tmp/hook-debug.log) confirms:- Interactive session (bypassPermissions): hook fires, log populated, write succeeds
claude -p(any permission mode): hook never fires, log stays empty, write blockedclaude -p --dangerously-skip-permissions: same — hook never fires, write blocked
The protected-dir check runs at a layer below the PermissionRequest event system. In interactive mode it goes through PermissionRequest (hookable). In
-pmode it short-circuits to an immediate error return.Impact
This blocks
claude -psubprocess workflows that need to write to~/.claude/— e.g., skill creation/editing, self-maintenance pipelines, any automation that manages Claude Code configuration.Suggested fix
The protected-dir check in
-pmode should go through the same PermissionRequest path as interactive mode, giving hooks a chance to allow the write. Alternatively,--dangerously-skip-permissionsshould bypass the protected-dir check entirely (as the flag name implies).matthew-plusprogramming commented
on Mar 25, 2026 More actionsThis is still an issue
@alexey-pelykh's finding is accurate and well-documented. Quick confirmation from the hooks side:
Interactive mode: PermissionRequest hooks fire correctly for.claude/writes. The execution order is:- PreToolUse hooks run
- Built-in protected-directory checks run
- PermissionRequest hooks run (can override step 2)
- Tool executes
-pmode: Step 3 never happens. The protected-dir check in step 2 returns an immediate error, bypassing the PermissionRequest event entirely. This means hook-based workarounds (likeallow-claude-settings.shor @wdelhagen's hook) only work in interactive sessions.
Workaround for-pmode users: Currently none that I'm aware of. The--dangerously-skip-permissionsflag does not bypass the protected-dir check in-pmode either (as alexey-pelykh confirmed).
This is a core harness issue — the protected-dir check needs to go through the PermissionRequest path in all modes, not just interactive. Supporting the fix request.
and still an issue in 2.1.84 @bcherny
yeah, can confirm this bug is BACK or never truly solved. This is a huge productivity blocker for people like me that fire and forget a dozen tasks at a time only to come back and find nothing done. Seriously you guys need to learn about regression testing... these are simple things that shouldn't ever go backwards... ever... maybe teach claude that next?
- added a commit that references this issue
on Mar 26, 2026 Still broken on Claude Code VScode extension v 2.1.84
@bcherny — the fix from this issue didn't hold. Multiple users confirm the problem persists on v2.1.84:
- [Bug] Permissions repeatedly requested despite bypass permissions enabled #36887: "Still broken on v2.1.84 in the VSCode extension"
- [Bug] Bypass permissions mode resets to ask permissions on every edit #39350: "Bypass permissions mode resets to ask permissions on every edit"
- Permission mode resets from 'Bypass permissions' to 'Edit automatically' mid-session #39057: "Permission mode resets from 'Bypass permissions' to 'Edit automatically' mid-session"
The protected directory prompt also interacts badly with the mode selector — clicking "Yes, allow all edits this session" silently downgrades the mode from Bypass to Edit Automatically, which then causes all subsequent operations to prompt.
I've mapped the full dependency tree (12+ issues, two correlated branches, trail going back to #2933 from July 2025) in a consolidated meta-issue: #39523.
Would appreciate this being reopened or the meta-issue being used as the tracking issue. This is a significant pain point for anyone running autonomous agent workflows.
This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.
- locked as resolved and limited conversation to collaborators
on Apr 3, 2026
Environment
--dangerously-skip-permissionsProblem
v2.1.78 introduced a change: "Fixed
.git,.claude, and other protected directories being writable without a prompt inbypassPermissionsmode."This means writing to any path containing
.claude/now requires a confirmation prompt, even when the user has explicitly opted into bypass mode. There is no override flag.This breaks a core daily workflow: creating and editing skills. Skills live in
.claude/skills/— by design. Every time Claude creates or updates a skill file, the user must click "OK" on a prompt that adds zero security value, because the user already opted into full bypass.Evidence
We track all tool calls in a metrics database. In our session today:
.claude/skills/rust-testing-patterns/SKILL.md: 8 seconds (the user confirming the prompt)This is the only Write that triggered a prompt. Same session, same permissions, same user.
Why this is counterproductive
1. Click fatigue destroys security
The entire field of security UX agrees: prompts that always get approved train users to click "OK" without reading. This is exactly what UAC on Windows taught us — when every action triggers a prompt, users develop muscle memory to dismiss it. You are not adding security; you are adding a speed bump that teaches users to ignore security prompts.
If you want
.claude/protection to mean something, it needs to fire rarely and for genuinely dangerous operations — not on every skill creation.2. No override flag forces worse workarounds
Since there's no
allowProtectedDirssetting or similar, users who need this workflow (and there are many — skills are a first-class Claude Code feature) will build workarounds:/tmp/skill.md, thenmv /tmp/skill.md .claude/skills/my-skill/SKILL.mdvia Bash (which isn't subject to the Write tool check).claude/after the session endssedorcat >via Bash to write files that the Write tool won't touchAll of these are less visible, less auditable, and harder to review than a normal Write tool call. The "security fix" pushes the operation into a channel with less oversight. That's the opposite of the goal.
3. The user already consented
--dangerously-skip-permissionsis not something users stumble into. The flag name contains "dangerously." The startup warning is explicit. The user made a deliberate choice. Overriding that choice for a subset of directories — without documenting it, without providing an opt-out — undermines trust in the permission system.If
bypassdoesn't meanbypass, what does it mean?Proposed fix
Minimum: Add a setting like
permissions.allowProtectedDirectoryWrites: truethat disables the prompt for.claude/,.git/, etc. when the user explicitly opts in. Respect it in bypass mode.Better: In bypass mode, skip ALL prompts. That's what bypass means. If Anthropic wants to protect
.claude/in non-bypass modes, that's reasonable — but bypass mode is the user saying "I accept the risk."Best: Make
.claude/skills/specifically exempt. Skills are a first-class feature. Claude creating skills is an expected, encouraged workflow. Prompting for confirmation on it is like a text editor asking "Are you sure you want to save?" every time. [HUMAN NOTE: Point 2 we need still, so this is not really "Best" for the dangerous skip case, just I guess for normal users. Though honestly not sure what else did my claude have to edit. MCPs possible? - just give me back my "I know what I am doing" - or to be more exact, I have safguards, he cant break stuff permanently, trust me..]Related issues
~/.claude/**permission issue (CLOSED by this change)