Memory feature's own directory (~/.claude/projects/<id>/memory/) is blocked by the .claude sensitive-file guardrail — no way to pre-authorize

Status Open
Reported on v2.1.216
Maintainer reply None cached
Activity 0 comments · opened Jul 21, 2026

Summary

Claude Code's own memory feature stores memories in ~/.claude/projects/<project-id>/memory/. That path sits inside .claude/, which the sensitive-file guardrail protects — so every single memory write requires an interactive approval, and there is no way to pre-authorize it. On a normal working day that is a dozen-plus prompts for a first-party feature the system prompt actively instructs the model to use ("write to it directly with the Write tool").

.claude/ already has an exemption list — skills, agents, commands, worktrees and scheduled_tasks.json do not trip the check. Request: add the memory directory to that list, or add an opt-in setting that does.

Reproduction

claude -p 'Use the Write tool to create ~/.claude/projects/<project-id>/memory/probe.md with the line "test"'
Claude requested permissions to edit <path> which is a sensitive file.

A control write to %TEMP% with an equivalent allow rule succeeds silently, so the allowlist itself is working — the .claude/ path is the differentiator.

What I tested (all denied)

| Attempt | Result |
|---|---|
| Write(~/.claude/projects/*/memory/**) in user settings | Not consulted — the CLI itself warns that only Edit(path) rules apply to file tools (helpful warning, thank you) |
| Edit(~/.claude/projects/*/memory/**) in user settings | Rule matches, guardrail overrules it |
| Bare Write / Edit in project settings.local.json | Overruled |
| PreToolUse hook returning permissionDecision: "allow" | Hook demonstrably fires (logged its own stdin and output); decision ignored |
| --allowedTools with an absolute (non-~) path | Ignored |
| Control: same write to %TEMP% | Allowed silently |

Two further observations that make this unworkable rather than merely noisy:

  1. "Yes, and don't ask again" cannot stick. Session always-allow rules whose content resolves under ~/.claude/ are explicitly filtered out before evaluation, so the prompt returns every time — matching the reports in #43001 and #16762.
  2. The check runs before the allow rules. In the file-permission evaluator the sensitive-file check is consulted ahead of the allow-rule lookup, which is why no rule in any settings scope can reach it. (Minified symbols in 2.1.216, in case it helps locate: the check is _it/oit_s_, called from Ilt before iit; the directory list is aWd.)

Identical behaviour in 2.1.215, so this is not a regression — it is the memory feature landing inside a pre-existing protected tree.

Why this isn't a duplicate of the earlier reports

#41615, #66525, #54189, #37181 and #36282 all ask for the broad version: let permissions.allow, hooks or bypass mode override the .claude/ guardrail generally. That is a much larger security question and I'm not asking for it. #41615 was closed by the stale bot with "please open a new issue if this is still relevant" rather than by a decision, so I'm filing the narrow case separately.

This report is specifically about a first-party feature whose designated storage location is blocked by the product's own guardrail. The user never chose that path; the harness did.

Suggested resolution

Add memory to the existing .claude/ exemption list, next to skills, agents, commands and worktrees.

For the record, the trade-off isn't zero: memories are injected into the context of future sessions, so an auto-approved memory write is a persistence channel a prompt injection could aim at. That's a real difference from skills/commands, and if it's the reason for the current behaviour, then an explicit opt-in setting (rather than a blanket exemption) would be the better shape — as long as something exists, since today nothing does. The status quo also trains users toward the genuinely worse workaround of writing .claude/ files through Bash, which skips the Write/Edit protection entirely.

Environment

  • Claude Code 2.1.216 (VS Code extension native binary), also verified on 2.1.215
  • Windows 11
  • Verified interventionally on 2026-07-21

View original on GitHub ↗