[BUG] VS Code extension session history empty on Windows when project is on mapped network drive (fs.realpath resolves to UNC, breaking project-key hash)

Resolved 💬 3 comments Opened Apr 17, 2026 by xmutantson Closed Apr 17, 2026

Summary

On Windows, when a project folder lives on a mapped network drive (e.g. X: mapped to \\server\share), the Claude Code VS Code extension's "past conversations" clock icon shows no sessions. The .jsonl session files exist on disk and claude --resume from a terminal lists them correctly. The extension's list_sessions_request returns an empty array; clicking the clock then spawns a fresh session (extension log: launch_claude ... resume: undefined), which effectively clobbers the current scrollback.

Root cause

The extension's cwd-normalizer calls fs.realpath(cwd).normalize("NFC"). On Windows, fs.realpath resolves mapped network drives to their UNC targets. So X:\myproject becomes \\server\share\myproject. The extension's project-key hasher (str.replace(/[^a-zA-Z0-9]/g, "-")) then produces --server-share-myproject instead of X--myproject. The claude.exe native binary creates ~/.claude/projects/X--myproject/ using the drive-letter form, so the extension's lookup never matches the actual on-disk directory. The directory resolver returns undefined and listSessions returns [].

Reproduced deterministically:

> python -c "import os; print(os.path.realpath('X:\\myproject'))"
\\server\share\myproject

Whereas claude.exe on the same cwd writes to ~/.claude/projects/X--myproject/.

Repro

  1. On Windows, map a network drive: net use X: \\192.168.1.100\share
  2. Create a project folder on the drive: mkdir X:\myproject
  3. Open X:\myproject in VS Code with the Claude Code extension
  4. Have at least one conversation to create a session
  5. Close VS Code fully, reopen
  6. Click the clock icon → no sessions shown
  7. Terminal claude --resume in the same folder → sessions listed correctly

Expected

Clock icon lists past sessions. Same behavior as on C: or on non-mapped paths.

Actual

Empty list. Clicking clock spawns a fresh session, visually clobbering the current scrollback.

Affected versions

Confirmed in 2.1.112 and 2.1.113 (latest as of 2026-04-17). The vulnerable code is minified but identifiable by this pattern, unchanged between the two versions apart from symbol renames:

async function <fn>(K){try{return(await <fs>.realpath(K)).normalize("NFC")}catch{return K.normalize("NFC")}}

In 2.1.112 this is named up using fs alias W3; in 2.1.113 it is Gl using fs alias M3.

Suggested fix

Any one of:

  • Skip realpath on Windows. Cheapest fix; makes the extension match claude.exe's behavior:

``js
async function up(K){
if (process.platform === "win32") return K.normalize("NFC");
try { return (await W3.realpath(K)).normalize("NFC") }
catch { return K.normalize("NFC") }
}
``

  • Apply realpath consistently in claude.exe too, so the write and read paths agree.
  • Add a fallback in the directory resolver: if readdir(Kq4(K)) fails, scan ~/.claude/projects/*/ and match by reading a .jsonl's embedded cwd field.

Local workaround

Patching extension.js with the if (process.platform === "win32") short-circuit in the vulnerable function fixes the issue on 2.1.112. I have a pattern-based re-apply script that survives version bumps; happy to share if useful.

Related (different root causes)

  • #22215 — cross-project cache contamination on macOS (open)
  • #18619 — sessions-index.json not updating
  • #31787 — VS Code + Desktop simultaneous use on Windows (closed as duplicate)

None of the above reference mapped network drives or the realpath/UNC interaction. This appears to be a new variant specific to Windows + mapped drives.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗