Project CLAUDE.md at a drive/filesystem root (subst drive / repo at C:\) is silently not loaded
What happened?
Project memory (CLAUDE.md / .claude/CLAUDE.md) is silently not loaded when the project directory is a drive/filesystem root — e.g. a subst drive on Windows (subst U: D:\repo, then launch from U:\), or a repo checked out directly at D:\.
Project settings.json, skills, commands, and hooks under <root>\.claude\ do load correctly (they resolve directly against cwd). Only the CLAUDE.md memory is missing, which makes this easy to miss and confusing to diagnose.
Root cause
Project-memory discovery walks the ancestors of cwd and excludes the filesystem root:
let u = [], p = originalCwd; // e.g. "U:\"
while (p !== path.parse(p).root) { // stops BEFORE pushing the root
u.push(p);
p = path.dirname(p);
}
for (const v of u.reverse()) {
load(path.join(v, "CLAUDE.md"));
load(path.join(v, ".claude", "CLAUDE.md"));
}
On Windows path.win32.parse("U:\\").root === "U:\\", so when cwd is the drive root the loop body runs zero times — the ancestor set is empty and neither U:\CLAUDE.md nor U:\.claude\CLAUDE.md is ever examined. (POSIX has the same shape for a repo at /.)
Contrast a normal deep cwd:
U:\→ ancestors =[]← nothing loaded (bug)D:\repo→ ancestors =["D:\repo"](D:\root excluded) →D:\repo\.claude\CLAUDE.mdloaded ✔
Note: on Windows a subst drive's cwd is kept as-is (U:\) and is not realpath-resolved to the underlying D:\repo, so the deep-path code path is never reached. (The session state dir confirms this: ~/.claude/projects/U--/.)
Steps to reproduce
subst U: D:\some\repo(or use any repo located directly at a drive root)- Put instructions in
U:\.claude\CLAUDE.md(orU:\CLAUDE.md). cd /d U:\ && claude/memory— the project CLAUDE.md is absent. Project skills/commands fromU:\.claude\are present, confirming.claude\itself is found.
Expected
The CLAUDE.md / .claude/CLAUDE.md located at the drive-root project directory should load, the same way .claude/settings.json, skills, and commands there already do.
Suggested fix
Make the ancestor walk inclusive of the root, e.g.:
let u = [], p = originalCwd;
while (true) { u.push(p); const parent = path.dirname(p); if (parent === p) break; p = parent; }
so the root directory itself is included as a candidate.
Work-arounds (for others hitting this)
- Launch from the real path (
D:\some\repo) instead of thesubstdrive. - Or remap subst to the parent (
subst U: D:\some, work inU:\repo— a non-root path). - Or set env
CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1and launchclaude --add-dir D:\some\repo(loads that dir's CLAUDE.md through the normal pipeline, so subagents get it too).
Environment
- Claude Code version: 2.1.217
- Platform: Windows 11 (26100); reproduced with a
substdrive root. Logic also affects any repo at a bare drive root / POSIX/.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗