/doctor reports ~/.local/bin not in PATH on Windows when it actually is (case-sensitive comparison)
Summary
On Windows, /doctor emits a false positive: it claims the native-install directory C:\Users\<user>\.local\bin is not in PATH when in fact it is — both in the User PATH registry key and in the live $env:Path. The likeliest cause is a case-sensitive PATH-membership check; the persisted entry on my system is lowercase (c:\users\<user>\.local\bin), and the warning quotes the mixed-case form.
Environment
- Claude Code: 2.1.133
- OS: Windows 11 Pro 10.0.26200
- Shell: PowerShell 7
- Native install:
C:\Users\<user>\.local\bin(containsclaude.exe,uv.exe,uvx.exe, etc., installed by the uv installer)
Reproduction
- Install the native Claude Code build, which places binaries in
C:\Users\<user>\.local\bin. - Have that directory added to the User PATH in lowercase form (the uv installer writes it lowercased on at least some Windows setups).
- Run
/doctorin any session.
Expected
/doctor recognises the directory as on PATH and emits no warning.
Actual
Native installation exists but C:\Users\<user>\.local\bin is not in your PATH
Suggested fix: Add it by opening: System Properties → Environment Variables → ...
Evidence
Live $env:Path (relevant excerpt):
...;C:\Users\<user>\scoop\apps\python311\current;c:\users\<user>\.local\bin;C:\Users\<user>\scoop\shims;...
HKCU:\Environment Path value (relevant excerpt):
...;C:\Users\<user>\scoop\apps\python311\current;c:\users\<user>\.local\bin;C:\Users\<user>\scoop\shims;...
Note the lowercase c:\users\<user>\.local\bin. claude.exe and the other native binaries resolve correctly from any new shell, confirming PATH is functionally fine.
Suspected cause
The PATH-membership check appears to compare strings case-sensitively (e.g. path.split(';').includes('C:\\Users\\<user>\\.local\\bin') with no normalisation). On Windows, PATH lookups are case-insensitive — both NTFS and the loader treat C:\ and c:\ as identical — so the check should fold case before comparing.
Suggested fix
On Windows, lowercase both sides before the membership check:
const onPath = (dir: string, p: string) => {
const norm = (s: string) =>
process.platform === 'win32' ? s.toLowerCase() : s;
return p.split(';').map(norm).includes(norm(dir));
};
Consider also calling path.normalize on each side to handle trailing slashes (c:\users\<user>\.local\bin\ vs c:\users\<user>\.local\bin).
Workaround
None needed at runtime — the path is functionally on PATH. The /doctor warning can be silenced cosmetically by rewriting the User PATH entry in mixed case, e.g. via [Environment]::SetEnvironmentVariable('PATH', ..., 'User').
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗