[BUG] Path encoding collision causes unrelated projects to share sessions and memory
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?
Bug Description
Claude Code uses a path encoding scheme to create project data directories under ~/.claude/projects/. The encoding simply replaces / with -, which causes a hash collision between two completely different filesystem paths.
In our monorepo setup, we have two unrelated services at different directory levels:
| Path | Description |
|---|---|
| ~/work/data-platform/datahub-api-proxy | Standalone API proxy service (its own repo) |
| ~/work/data-platform/datahub/api-proxy | API proxy sub-module within the DataHub monorepo |
Both paths encode to the same directory name -work-data-platform-datahub-api-proxy under ~/.claude/projects/, causing them to share session history, memory files, and project state.
Steps to Reproduce
- Create two directories:
mkdir -p ~/work/data-platform/datahub-api-proxy
mkdir -p ~/work/data-platform/datahub/api-proxy
- Open Claude in
~/work/data-platform/datahub-api-proxyand start a session. - Open Claude in
~/work/data-platform/datahub/api-proxy. - Run
/sessions— you will see the session from the other directory in the list. - Both directories also share the same
memory/folder, so memories saved in one project are automatically loaded in the other, even though the projects are unrelated.
Root Cause
The encoding is a simple path.replace('/', '-'), which is a lossy mapping:
datahub-api-proxy (single directory with hyphens)
datahub/api-proxy (two directories: datahub/ → -datahub-, api-proxy)
Both produce -datahub-api-proxy after encoding.
This is effectively a hash collision — any pair of paths where A/B-C and A/B/C coexist will collide. Common patterns that trigger this:
foo-bar/bazandfoo/bar-bazmy-appandmy/appdata-hub/apianddata/hub-api
Expected Behavior
Each distinct filesystem path should map to a unique project data directory. The encoding should be bijective (reversible), so that no two real paths produce the same encoded name.
Actual Behavior
Two unrelated paths share the same ~/.claude/projects/ subdirectory, leading to:
- Session list pollution — sessions from one project appear in another unrelated project's
/sessionslist - Memory cross-contamination —
memory/files (user, feedback, project, reference) are shared between unrelated projects, causing incorrect context to be loaded automatically - Potential concurrent write issues — running Claude in both directories simultaneously causes them to read/write the same state files
Environment
- Claude Code version: 2.1.150
- OS: macOS (Darwin 25.5.0)
Suggested Fix
Use an encoding that doesn't produce collisions:
- Base64-encode the full path (URL-safe base64, strip padding)
- SHA-256 hash of the path (truncated to 32 chars for readability)
- Percent-encode
/as%2Finstead of replacing with-
Any of these would be collision-free while remaining reasonably debuggable.
What Should Happen?
Each distinct filesystem path should map to a unique project data directory. The encoding should be bijective (reversible), so that no two real paths produce the same encoded name.
Error Messages/Logs
Steps to Reproduce
- Create two directories:
mkdir -p ~/work/data-platform/datahub-api-proxy
mkdir -p ~/work/data-platform/datahub/api-proxy
- Open Claude in
~/work/data-platform/datahub-api-proxyand start a session. - Open Claude in
~/work/data-platform/datahub/api-proxy. - Run
/sessions— you will see the session from the other directory in the list. - Both directories also share the same
memory/folder, so memories saved in one project are automatically loaded in the other, even though the projects are unrelated.
Claude Model
None
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
2.1.150
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
iTerm2
Additional Information
_No response_
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗