macOS: Session history not found for paths with Unicode combining marks (NFD vs NFC)
Summary
On macOS (APFS), when a VSCode workspace path contains characters with combining marks (e.g., Japanese dakuten in 共有ドライブ), Claude Code's VSCode extension fails to load existing local session history. The same visual path in NFC (composed form) produces a different project directory key than NFD (decomposed form).
Environment
- OS: macOS 15.4.1 (APFS)
- VSCode Claude Code extension: 2.1.25 / 2.1.27 (native-binary)
- Config dir:
~/claude-data(viaCLAUDE_CONFIG_DIR)
Workspace Path
/Users/<me>/Library/CloudStorage/GoogleDrive-<email>/共有ドライブ/Uravation/Uravation_PARA
The key characters are ドライブ (contains dakuten on ド and ブ).
Root Cause
The project directory name is derived by t.replace(/[^a-zA-Z0-9]/g, "-") (the tm() function in extension.js).
- macOS APFS stores paths in NFD (decomposed):
ド=ト(U+30C8) + combining dakuten (U+3099) - VSCode provides workspace paths in NFC (composed):
ド= U+30C9
This means the combining mark in NFD becomes an extra - in the sanitized directory name:
| Form | Sanitized directory name | Dash count |
|------|---|---|
| NFD (on disk) | ...-com----------Uravation-... | 10 dashes |
| NFC (VSCode) | ...-com--------Uravation-... | 8 dashes |
The extension looks for the NFC-derived directory, but sessions are stored under the NFD-derived directory → history appears empty.
Steps to Reproduce
- On macOS, open a folder in VSCode whose path contains Japanese dakuten characters (e.g.,
共有ドライブfrom Google Drive shared drives) - Use Claude Code to create sessions (they get saved to disk)
- Close and reopen VSCode / start a new session
- Session history shows empty / "no previous sessions"
Expected Behavior
Session history should be found regardless of Unicode normalization form.
Suggested Fix
Normalize the path to a canonical form (e.g., path.normalize('NFD') on macOS, or path.normalize('NFC') consistently) before deriving the project directory name in tm().
// Before
function tm(t) {
return join(yG(), t.replace(/[^a-zA-Z0-9]/g, "-"));
}
// After (example)
function tm(t) {
return join(yG(), t.normalize('NFC').replace(/[^a-zA-Z0-9]/g, "-"));
}
A backward-compatible approach would also check for the legacy (NFD-derived) directory if the normalized one doesn't exist.
Workaround
Create a symlink from the NFC-derived name to the NFD-derived directory:
cd ~/claude-data/projects # or ~/.claude/projects
ln -s "./<NFD-directory-name>" "./<NFC-directory-name>"
Additional Context
- Only affects paths with Unicode combining marks (dakuten, handakuten, etc.)
- Paths without combining marks (e.g.,
開発,漢字) are unaffected since NFC = NFD for those characters - This is a common issue on macOS with Google Drive shared drives (
共有ドライブ)
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗