Project-scope permission grant strips unknown top-level keys from .claude/settings.json

Resolved 💬 2 comments Opened Jun 8, 2026 by jaideep-dhumal-quorum Closed Jul 15, 2026

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?

When Claude Code writes a new permission rule to project-level .claude/settings.json (triggered by approving an "Always allow (project)" permission prompt), it appears to drop top-level keys it doesn't recognize. In my case, the extraKnownMarketplaces and enabledPlugins blocks were silently deleted while a new permissions.allow entry was being added.

This is destructive — those keys are part of the documented schema (used to register plugin marketplaces and enable plugins via bootstrap scripts), and losing them silently disables plugins for everyone who pulls the next commit.

Secondary issue in the same write: the new permission entries embed the user's absolute home-directory path, which doesn't generalize to other contributors when the file is committed.

What Should Happen?

  • A new entry is added to permissions.allow.
  • All other top-level keys (extraKnownMarketplaces, enabledPlugins, and any other valid keys) are preserved verbatim.
  • Permission rules generated from "Always allow (project)" do not contain absolute user-home paths; either the paths are normalized, or "Always allow" for home-dir paths writes to settings.local.json / user scope instead of project scope.

Error Messages/Logs

diff --git a/.claude/settings.json b/.claude/settings.json
@@ -7,18 +7,9 @@
       "Bash(git add *)",
       "Bash(git commit *)",
       "Bash(git push *)",
-      "Bash(npx some-bootstrap-cli *)"
+      "Bash(npx some-bootstrap-cli *)",
+      "Bash(ls \"C:\\\\Users\\\\<user>\\\\.claude\\\\projects\\\\<project-slug>\\\\memory\\\\\" 2>&1 | head -30)",
+      "Read(//c/Users/<user>/.claude/projects/<project-slug>/**)"
     ]
-  },
-  "extraKnownMarketplaces": {
-    "example-marketplace": {
-      "source": {
-        "source": "github",
-        "repo": "example-org/example-marketplace-repo"
-      }
-    }
-  },
-  "enabledPlugins": {
-    "example-plugin@example-marketplace": true
   }
 }

Steps to Reproduce

  1. In any project, create .claude/settings.json with at least one top-level key besides permissions. For example:

{
"permissions": { "allow": ["Bash(npm view *)"] },
"extraKnownMarketplaces": {
"example-marketplace": { "source": { "source": "github", "repo": "example-org/example-marketplace-repo" } }
},
"enabledPlugins": { "example-plugin@example-marketplace": true }
}

  1. Open Claude Code in that project.
  2. Run any command that will trigger a permission prompt (e.g. ls some/new/path).
  3. On the prompt, pick "Always allow (project)" — the option that writes to project-level .claude/settings.json.
  4. Inspect .claude/settings.json.

Observed: the new permission entry is added under permissions.allow, but extraKnownMarketplaces and enabledPlugins are deleted entirely. The permission entries that get written also embed the user's absolute home-directory path verbatim.

Expected: the new permission entry is added and the other top-level keys are preserved untouched.

Claude Model

Opus

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.165

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

VS Code integrated terminal

Additional Information

Secondary observation (possibly a separate issue):

The auto-written permission entries embedded the absolute Windows path including my username (C:\Users\<user>\.claude\projects\<project-slug>\...). When .claude/settings.json is checked into version control (the documented purpose of project-scope settings, alongside settings.local.json for personal overrides), these paths leak the local user's home directory into the shared team file and don't generalize to other contributors.

Possible mitigations:

  • Strip or normalize user-home paths before writing to project scope.
  • OR: default "Always allow" writes for paths under the user's home directory to settings.local.json instead of project scope.

Workaround in the meantime:

Pick "Always allow (local)" or "Always allow (user)" rather than "Always allow (project)" — those land in settings.local.json (gitignored) or ~/.claude/settings.json respectively and don't touch the team-shared file.

Impact:

  • Silent regression of plugin/marketplace configuration whenever any team member triggers a project-scope permission grant. The next git pull propagates the deletion to everyone.
  • User-specific absolute paths leak into team-shared settings via permission rules — bad for both portability and incidentally exposes Windows usernames in committed files.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗