Desktop app: settings.local.json Write/Edit/NotebookEdit permission deny rules not enforced

Status Open
Maintainer reply None cached
Activity 0 comments · opened Sep 30, 2026

Environment

  • Claude Code desktop app, Code tab (not the terminal CLI directly)
  • Project has a committed .claude/settings.json and a git-ignored .claude/settings.local.json, both with permissions.deny arrays

Setup

.claude/settings.json (committed):

{
  "permissions": {
    "deny": [
      "Read(**/.env)", "Read(**/.env.*)", "Read(**/*.pem)", "Read(**/*.key)",
      "Read(~/.aws/credentials)", "Read(~/.ssh/id_*)",
      "Bash(env)", "Bash(printenv)"
    ]
  }
}

.claude/settings.local.json (git-ignored, project-local):

{
  "permissions": {
    "deny": [
      "Edit(/absolute/path/to/some-other-repo/**)",
      "Write(/absolute/path/to/some-other-repo/**)",
      "NotebookEdit(/absolute/path/to/some-other-repo/**)"
    ]
  }
}

Expected

Per the settings docs, .claude/settings.local.json (project-local, level 3) should override/merge with .claude/settings.json (level 4) with the same precedence everywhere Claude Code runs, including the desktop app. deny rules are documented to "apply right away." So a Write or Edit tool call targeting a path matched by a Write(...)/Edit(...) deny rule in settings.local.json should be blocked, the same way a Read call matched by a Read(...) deny rule in settings.json is blocked.

Actual

  • Read calls matching settings.json's Read(...) deny rules are blocked correctly, with an explicit "File is in a directory that is denied by your permission settings" error.
  • Write calls matching settings.local.json's Write(...) deny rule are not blocked:
  • In session permission mode auto: the Write silently succeeded — no denial, no prompt.
  • In session permission mode default (switched mid-session via the app's own permission-mode control): the same Write attempt did not get an explicit rule-based denial either — it fell through to an ordinary interactive approval prompt, as if no deny rule existed at all, and only got blocked because a human manually rejected the prompt.
  • Re-tested an Edit against a pre-existing tracked file with a matching Edit(...) deny rule (present in settings.local.json before this test, not newly added) — same result: not blocked as a rule match, required manual rejection in default mode.

So there's a clear asymmetry: Read deny rules from the committed settings file enforce correctly; Write/Edit/NotebookEdit deny rules from the local settings file do not enforce as rule-based denials in either auto or default permission mode — in the desktop app specifically. I haven't tested the terminal CLI to see if it reproduces there too.

Impact

This defeats a guardrail pattern meant to keep an agent session from ever committing to or editing files in an unrelated, read-only reference repo path configured via settings.local.json — the rule is present, syntactically valid, and silently doesn't fire.

Happy to provide more repro detail or a minimal test repo if useful.

View original on GitHub ↗