Repository navigation
[BUG] bypassPermissions v2.1.81: .claude/skills/ not exempt from protected directory prompt despite documentation #37157
Description
Activity
- addedbugSomething isn't workingSomething isn't workinghas reproHas detailed reproduction stepsHas detailed reproduction steps
on Mar 21, 2026 Found 3 possible duplicate issues:
.claude/skills/edits prompt for permission despite being documented as exempt (regression in 2.1.79) #36497- Regression: .claude/skills/ writes prompt for confirmation in bypassPermissions mode since 2.1.78 #36396
- Bug: SKILL.md creation prompts for permission even in bypass mode #36923
This issue will be automatically closed as a duplicate in 3 days.
- If your issue is a duplicate, please close it and 👍 the existing issue instead
- To prevent auto-closure, add a comment or 👎 this comment
🤖 Generated with Claude Code
Same pattern as #37253 — `
/.claude/` is a protected directory that even `bypassPermissions` doesn't bypass. The docs say `skills/` should be exempt, but the implementation doesn't match./.claude/hooks/approve-claude-dirs.sh" }]
Until the exemption is fixed, you can auto-approve with a PreToolUse hook:
```bash
INPUT=$(cat)
TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
[[ "$TOOL" != "Edit" && "$TOOL" != "Write" ]] && exit 0
case "$FILE" in
/.claude/skills/|/.claude/commands/|/.claude/agents/)
jq -n '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"allow","permissionDecisionReason":"skills/commands/agents auto-approved per docs"}}'
exit 0
;;
esac
exit 0
```
Settings:
```json
{
"hooks": {
"PreToolUse": [{
"matcher": "",
"hooks": [{ "type": "command", "command": "
}]
}
}
```Confirming this also affects Agent SDK
query()— with source-level root cause and working binary patchTested exhaustively in v2.1.81 (Linux/Docker,
@anthropic-ai/claude-agent-sdknpm package). The missing.claude/skillsexemption blocks Edit/Write in SDK subprocess mode. Two separate checks incli.jsneed the exemption.History: v2.1.78 added protected-directory checks for all
.claude/writes (#35646). A follow-up fix added exemptions for.claude/commandsand.claude/agentsbut missed.claude/skills. TheuHYfunction's existingworktreesexemption pattern was not extended to cover skills/agents/commands either. This patch completes both exemptions.Root cause: two functions in
dN1's safety cascade (function names from our build's minification —sXTin the OP maps toLP8in my build; the checks below are additional to that exemption function)dN1(the write-safety check called fromYw6) runs three checks sequentially. A.claude/skills/path fails at both step 2 and step 3:rEq— Windows path patterns → passesIHY— checks if path is a.claude/protected path → returns true for skills/ →safe: falseuHY— checks path segments againsthHY = [".git", ".vscode", ".idea", ".claude"]→ returns true for.claudesegment →safe: false
IHYalready has.claude/skillsin its check list alongside commands and agents — but it flags all three as protected rather than exempt.uHYhas an existing exemption for.claude/worktrees(breaks out of the check) but not for skills/agents/commands.Note:
LP8/sXT(the exemption function identified in the OP) is used for file search/ripgrep scoping, not the permission cascade. Adding.claude/skillstoLP8alone does not fix the edit block — bothIHYanduHYindN1need to be patched.Working binary patch (two changes in
cli.js):Patch 1 —
IHY: Settings files remain protected viaWU1; commands/agents/skills no longer flagged:Find: return wk(A,q)||wk(A,K)||wk(A,_)} Replace: return!1}Patch 2 —
uHY: Add skills/agents/commands to the existing worktrees exemption:Find: if(O===".claude"){let $=K[Y+1];if($&&yZ($)==="worktrees")break} Replace: if(O===".claude"){let $=K[Y+1];if($&&(yZ($)==="worktrees"||yZ($)==="skills"||yZ($)==="agents"||yZ($)==="commands"))break}What remains protected after patch:
.claude/settings.json,.claude/settings.local.json— protected (WU1+uHY).claude/rules/,.claude/hooks/— protected (uHYcatches.claudewithout exemption).claude/skills/,.claude/agents/,.claude/commands/— exempt (matching docs and pre-v2.1.78 behavior)
Apply with Python:
with open('node_modules/@anthropic-ai/claude-agent-sdk/cli.js', 'r') as f: content = f.read() content = content.replace( 'return wk(A,q)||wk(A,K)||wk(A,_)}', 'return!1}', 1) content = content.replace( 'if(O===".claude"){let $=K[Y+1];if($&&yZ($)==="worktrees")break}', 'if(O===".claude"){let $=K[Y+1];if($&&(yZ($)==="worktrees"||yZ($)==="skills"||yZ($)==="agents"||yZ($)==="commands"))break}', 1) with open('node_modules/@anthropic-ai/claude-agent-sdk/cli.js', 'w') as f: f.write(content)
Verified: Edit tool works with 0 denials in SDK
query()mode after patch. BothbypassPermissionsandacceptEditsmodes work correctly. Settings files remain protected.Note on hook workarounds:
PreToolUsewithpermissionDecision: "allow"fires but doesn't override (runs beforedN1).PermissionRequesthooks never fire in SDK subprocess mode —dN1returns{behavior: "ask"}before thePermissionRequestdispatch path is reached, and the SDK subprocess treats the unresolved ask as a denial.Environment: Claude Code 2.1.81,
@anthropic-ai/claude-agent-sdk(npm), Node 20.20.0, Linux (Docker)Reacted by Adam and Alexander LyzhovSame issue here. Running two autonomous Claude Code agents 24/7 on a VPS via
--channels plugin:telegram@claude-plugins-official --dangerously-skip-permissions. Both agents constantly get blocked on the "modify config files" prompt when writing to.claude/skills/.Since these are headless agents communicating only via Telegram, there's no one watching the terminal to approve. The permission relay (
claude/channel/permission) doesn't cover this prompt category either, so it doesn't appear in Telegram — it just silently blocks.Current workaround: telling agents to use
cat >via Bash instead of Write/Edit for.claude/paths, but they forget and get stuck regularly. Need manual intervention via tmux to unblock.Setup: Claude Code v2.1.81, Claude Max, Ubuntu 24.04, two agents running in tmux with
--dangerously-skip-permissions --channels.Adding
.claude/skillsto the exemption list alongside.claude/commandsand.claude/agentswould fix this completely..claude/plans/should also be added to the exemption list.Currently only
commandsandagentsare exempted in the code (withskillsdocumented but missing). Butplans/is equally non-dangerous — it's where Claude stores implementation plans for multi-session work. These are markdown files with no executable content, no hooks, no settings.In my setup (fully permissive: unrestricted
Edit/Write+bypassPermissions+skipDangerousModePermissionPrompt), the self-edit prompt only triggers for plans — memory writes to~/.claude/projects/*/memory/go through without prompting, but any write to<project>/.claude/plans/triggers the prompt every session.Suggested fix for the exemption function:
function sXT() { return [...nCK.filter(d => d !== ".git"), ".claude/commands", ".claude/agents", ".claude/skills", ".claude/plans"] }
All four subdirectories (
commands,agents,skills,plans) contain user-facing content that Claude routinely creates/updates — none of them are settings, hooks, or anything security-sensitive.Plugins can store their working data under the recommended path ~/.claude/plugins/data//. it should be also exempt alongside .claude/commands, .claude/agents, and .claude/skills.
I've been hitting this since v2.1.78 dropped. Now on v2.1.83 — still broken.
My workflow relies heavily on editing
.claude/skills/files for context archiving and knowledge persistence across sessions. Every single Edit/Write to a skill file triggers a permission prompt, even with:defaultMode: "bypassPermissions"skipDangerousModePermissionPrompt: true- Explicit
Edit(/.claude/skills/**)andWrite(/.claude/skills/**)in allow rules .claude/skillsinadditionalDirectories
None of these have any effect. The hardcoded safety check overrides everything.
What makes this even worse: approving "allow all edits during this session" doesn't persist. The next edit to a
.claude/skills/file prompts again. So it's not even a once-per-session annoyance — it's every single time.I've also tried the
PreToolUsehook workaround (returningpermissionDecision: "allow") — the hook fires but the safety check runs as a separate gate after it and prompts anyway.The documentation explicitly says
.claude/skills/should be exempt. The binary patch in @IMBurbank's comment above shows exactly what needs to change — it's literally adding"skills"to the existing"worktrees"exemption. This is a one-line fix that's been sitting here for weeks.Five versions without a fix or even an acknowledgment. Please prioritize this.
Still reproducible on Windows as of 2026-04-20.
This matches the existing
.claude/skillsexemption bug, but I'm adding a Windows repro because the behavior is still inconsistent with the docs.Environment
- OS: Windows
- Shell: PowerShell
- Permission mode:
bypassPermissions
Docs say
.claude/skillsshould be exempt from protected-directory prompts:
https://code.claude.com/docs/en/permissionsActual behavior
When Claude tries to create or edit files under:.claude/skills/<skill-name>/scripts/it still shows a permission prompt like:
Claude requested permissions to write to .../.claude/skills//scripts, but you haven't granted it yet.
The prompt includes choices such as:
- Yes
- Yes, and always allow access ...
- No
Expected behavior
No prompt at all for writes under.claude/skills/**, since the docs explicitly list that path as exempt.Impact
This breaks deterministic skill-authoring workflows on Windows even withbypassPermissions, because skill creation and editing still requires interactive confirmation.Related
Additional version detail for tracking:
Reproduced on:
- Claude Code 2.1.114
- Windows
- PowerShell
bypassPermissions
So this is still present well past the earlier reports around v2.1.78-v2.1.84.
- added a commit that references this issue
on Apr 25, 2026 This is a duplicate of #37765, which was fixed as of version 2.1.121.
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 May 7, 2026
Description
The permissions documentation states:
However, in v2.1.81,
.claude/skills/is not exempt from the protected directory prompt. Edits to files under.claude/skills/**trigger the "Do you want to make this edit?" prompt with the "Yes, and allow Claude to edit its own settings for this session" option — even withbypassPermissionsmode active.Root Cause (from source analysis)
The exemption function in the bundled binary only includes two of the three documented paths:
The docs promise
.claude/skillsis exempt, but the code doesn't include it.Steps to Reproduce
"defaultMode": "bypassPermissions"in settings.claude/skills/<name>/scripts/.claude/skills/Impact
This is particularly disruptive for projects that use
.claude/skills/extensively for automation, agent workflows, and domain-specific tooling. Every new session requires manual approval for the first.claude/skills/**edit, breaking autonomousclaude -p --dangerously-skip-permissionsworkflows.Related Issues
.claude/skillsexemption was not included in the fix)Environment
bypassPermissions+skipDangerousModePermissionPrompt: trueSuggested Fix
Add
.claude/skillsto thesXT()exemption function to match the documented behavior: