/doctor reports ~/.local/bin not in PATH on Windows when it actually is (case-sensitive comparison)

Resolved 💬 3 comments Opened May 8, 2026 by xxthunder Closed May 12, 2026

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 (contains claude.exe, uv.exe, uvx.exe, etc., installed by the uv installer)

Reproduction

  1. Install the native Claude Code build, which places binaries in C:\Users\<user>\.local\bin.
  2. Have that directory added to the User PATH in lowercase form (the uv installer writes it lowercased on at least some Windows setups).
  3. Run /doctor in 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').

View original on GitHub ↗

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