[BUG] Trust store uses literal path-string matching without normalization — same directory re-prompts trust across path-separator/case variants and version upgrades
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?
Environment:
- Claude Code version: 2.1.197 (also reproduced with historical entries from 2.1.139, 2.1.173)
- OS: Windows 11 Pro (10.0.26200)
- Shell: PowerShell 5.1
Summary:
The project trust store in ~/.claude.json (projects map) appears to key on the literal working-directory path string, without normalizing path separators (/ vs \) or drive-letter/segment casing. As a result, the exact same physical directory can accumulate multiple independent entries with inconsistent hasTrustDialogAccepted values, causing the trust dialog to reappear — and .claude/settings.local.json permission rules to be silently ignored — even though the user already accepted trust for that directory under a different path notation.
Suggested fix:
Normalize the working-directory path (case-fold + separator-normalize on Windows, resolve symlinks/junctions where applicable) before using it as the lookup/storage key in the projects trust map, and perform a one-time migration to merge/dedupe existing variant entries for the same physical directory.
What Should Happen?
Expected behavior:
Trust state should be keyed on a canonicalized path (case-folded on Windows, separators normalized, ideally resolved via something like fs.realpathSync/path.resolve) so the same physical directory is recognized as already-trusted regardless of how the cwd string was produced.
Error Messages/Logs
**Evidence (same physical directory: `C:\Users\shine\mba\claude mba`):**
| Key as stored in `~/.claude.json` | `hasTrustDialogAccepted` | `lastVersionBase` |
|---|---|---|
| `C:\Users\shine\mba\claude mba` (backslash) | `true` | (none recorded) |
| `C:\Users\shine\MBA\claude mba` (backslash, different segment case) | `true` | (none recorded) |
| `C:/Users/shine/mba/claude mba` (forward slash) | `false` | `2.1.197` |
| `C:/users/shine/mba/claude mba` (forward slash, lowercase segment) | `false` | `2.1.139` |
| `C:/Users/shine/MBA/claude mba` (forward slash, different segment case) | `false` | `2.1.197` |
Windows filesystem paths are case-insensitive and separator-agnostic — all five keys above resolve to the same physical folder — but the trust store treats them as five distinct, independently-tracked projects.
Steps to Reproduce
Steps to reproduce:
- Launch
claudein a directory using backslash-style path resolution (e.g., viacmd.exeor certain PowerShell contexts) and accept the trust dialog. - Later, launch
claudein the same directory but via a code path that resolves/passes the cwd using forward slashes (observed to happen after upgrading to a newer version, and also when launching via an SSH session using a Unix-style shell where paths are typed in lowercase, e.g./c/users/...). - Claude Code treats step 2 as an entirely new, untrusted project — the trust dialog reappears, and all
permissions.allowentries in.claude/settings.local.jsonare ignored until re-accepted.
Claude Model
Sonnet (default)
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
v2.1.197
Platform
Other
Operating System
Windows
Terminal/Shell
Windows Terminal
Additional Information
_No response_