[BUG] Local-scoped plugin fails to load on Windows with `plugin-cache-miss` due to case-sensitive `projectPath` comparison
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?
A local-scoped marketplace plugin that is installed correctly and whose cache exists on disk still fails to load in the VS Code extension on Windows with plugin-cache-miss.
The issue appears when the stored projectPath in installed_plugins.json uses a different drive-letter case than the extension's launch cwd (for example, C: vs c:). The plugin record is never matched because the lookup uses a strict, case-sensitive comparison, so the plugin cache is treated as missing even though it exists and validates successfully.
This makes the plugin's skills, commands, and MCP servers unavailable in the extension, while the CLI still reports the plugin as installed and valid.
What Should Happen?
Local-scope plugin resolution should match the current project against the installed plugin record using a case-insensitive, normalized path comparison on Windows.
A plugin whose cache directory exists and validates should load normally regardless of drive-letter case differences between the stored projectPath and the extension's current working directory.
Error Messages/Logs
[DEBUG] Loaded 1 installed plugins from C:\Users\<user>\.claude\plugins\installed_plugins.json
[DEBUG] Plugin not available for MCP: my-plugin@example-marketplace - error type: plugin-cache-miss
[DEBUG] Plugin loading errors: Plugin "my-plugin" not cached at C:\Users\<user>\.claude\plugins\cache\example-marketplace\my-plugin\4.35.0 — run /plugin to refresh
Steps to Reproduce
- On Windows, install a marketplace plugin at local scope into a project so that
installed_plugins.jsonstoresprojectPathwith an uppercase drive letter such asC:\Users\<user>\repos\my-project. - Launch VS Code so that the extension host starts with a lowercase drive letter in its working directory, such as
c:\Users\<user>\repos\my-project. - Open Claude Code in that workspace.
- Observe that the extension logs
plugin-cache-missand the plugin never loads, even though the plugin is present on disk and the CLI reports it as installed and enabled.
Claude Model
Not sure / Multiple models
Is this a regression?
Yes, this worked in a previous version
Last Working Version
2.1.179 confirmed by below comment.
Claude Code Version
2.1.201 (CLI and bundled extension binary)
Platform
AWS Bedrock
Operating System
Windows
Terminal/Shell
Other
Additional Information
related #74612 but with a different scope. Likely the same issue with path normalization
- Extension:
anthropic.claude-code-2.1.201-win32-x64 - Plugin:
my-plugin@example-marketplace - Scope:
local - Plugin version:
4.35.0 - The CLI (
claude plugin list/claude plugin validate) reports the plugin as installed and valid, while the VS Code extension reportsplugin-cache-miss. - Workaround confirmed: editing
installed_plugins.jsonto change theprojectPathdrive letter to match the extension's launch case resolves the issue until the next install/update/enable operation. - The issue reproduces with any local-scoped plugin, not just this one example.
Showing cached comments. Read the full discussion on GitHub ↗
3 Comments
I spent some time testing this yesterday to try to find exactly which version this broke in and confirm if this is actually a case-sensitivity issue and looks like that is exactly it. I started downgrading versions until I found one where it worked and it turns out this was working fine in 2.1.179 and broke in 2.1.181 (Note: I didn't see a published version for
2.1.180). The issue #74612 is related to this so a fix for this should fix that as well.A quick and easy way to reproduce it is to run
/reload-pluginsfrom the VSCode extension and observe the VSCode output logs for the Claude Code extension. You will see things like the following in a broken version:The test I did to confirm that it was indeed a case-sensitivity issue is as follows:
/reload-skillsto check the skill count in the "broken" state.~/.claude/plugins/installed_plugins.jsonand~/.claude/plugins/known_marketplaces.jsonto replace upper case drive letters with lower case drive letters (e.g.C:->c:)./reload-skillsand observe the skill count.If it worked, you should now see more skills coming from the plugins you loaded.
Note: This will work for a while, but eventually it will override the drive letters back to upper case as it updates plugins and marketplaces.
As a quick work around, downgrading to
2.1.179for both Claude CLI and VSCode extension works:Downgrade Claude CLI:
Downgrade Claude VSCode Extension:
2.1.179out of the listA few additional data points that may help pin down the fix (from diagnosis session using Opus):
1. The exact VS Code code path that lowercases the drive letter. The extension host's lowercase-
c:working directory isn't incidental — it comes fromuriToFsPath()in VS Code'ssrc/vs/base/common/uri.ts(also shipped as thevscode-urinpm package). TheURI.fsPathgetter callsuriToFsPath(this, /* keepDriveLetterCasing */ false), and with that flagfalseit executes:This is intentional, long-standing VS Code behavior (the
keepDriveLetterCasingopt-out exists precisely because normalization is the default). So the fix has to live on the Claude Code side — the extension will always hand over a lowercase drive letter and that won't change.2. The CLI writes uppercase
C:regardless of the shell's casing. I confirmed the uppercaseprojectPathis not inherited from the installing shell:claude plugin install --scope projectrecordedC:\...even when run from a Git Bash shell whosepwdwas lowercase/c/.... Verified across 4 independent installs (interactive CLI and via tooling). So this reproduces for any user regardless of how they install — it's not a quirk of one shell setup.3. It can manifest silently, not just as
plugin-cache-miss. In my case the project-scoped plugins' skills/commands simply didn't appear in the VS Code session at all, with no error or log line — while user-scoped plugins loaded fine in the same session. Same underlying casing mismatch, but worth noting the symptom isn't always theplugin-cache-missmessage; sometimes it's a silent absence.4. A more robust workaround for people who use both the CLI and VS Code. Editing
installed_plugins.jsonto lowercase theprojectPathin place fixes VS Code but then breaks the CLI (which matches on uppercase) — so you ping-pong between the two. Since each plugin's value is an array of install records, you can instead keep both casings — add a duplicate record with the opposite drive-letter casing (oneC:\..., onec:\..., both pointing at the same cacheinstallPath). Then whichever casing a client presents, one entry matches, and both environments work simultaneously. Still fragile (a later install/enable/update may rewrite or dedupe the entries), but it survives switching between CLI and VS Code.Additional evidence for the casing mismatch, beyond
installed_plugins.json:~/.claude/sessions/*.json(VS Code session) —"cwd": "c:\\...", "entrypoint": "claude-vscode"(lowercase)~/.claude/ide/*.lock—"workspaceFolders": ["c:\\..."](lowercase)Same CLI binary/version in both cases (
entrypoint: claude-vscoderuns the same binary) — only the drive-letter casing of the project path differs.Confirming this same root cause (case-sensitive comparison of a case-insensitive Windows path) also breaks
~/.claude.jsonproject-scoped config, not just plugin loading — so this isn'tarea:plugins-specific, it's a general Windows path-handling issue in Claude Code.Environment: Claude Code 2.1.232, Windows 11, project opened both via CLI (external PowerShell terminal) and via the VSCode extension.
What I found: opening the same project through the CLI and through the VSCode extension creates two separate entries under
projectsin~/.claude.jsonthat differ only in drive-letter case:The CLI-created entry accumulates real session state (
lastCost,lastDuration,lastSessionId,hasTrustDialogAccepted: true, etc.) while the VSCode-created entry stays mostly at defaults (hasTrustDialogAccepted: false) — so on Windows, trust approval and MCP config effectively have to be redone per-frontend.I dug into why the casing differs, since it seemed worth nailing down for a fix:
cd. Verified empirically:``
`PS> Set-Location d:\some\path
PS> node -e "console.log(process.cwd())"
D:\some\path
process.cwd()(Same result from Git Bash's spawned Node process —
/ libuv'suv_cwd()` returns uppercase.)So the mismatch isn't caused by user habit (typing
cd D:\...vscd d:\...) — it's a structural disagreement between how the CLI derives its cwd (raw OS-reported, uppercase) and how the VSCode extension derives its workspace path (normalized, lowercase). No amount of consistent typing on the user's side fixes it; the normalization has to happen on Claude Code's side, e.g. case-folding the drive letter (either direction, just needs to be consistent) before using a Windows path as aprojectskey — same fix this issue already proposes forinstalled_plugins.json/projectPathcomparison.Also worth linking as prior reports of the same underlying bug, all Windows-only path-casing issues, mostly closed as stale/duplicate without a fix landing: #18122, #45195, #46586, #19910, #25756, #56642.