claude update: false-positive "~/.local/bin is not in your PATH" warning when it actually is
Description
claude update prints the warning:
Warning: Native installation exists but ~/.local/bin is not in your PATH
Fix: Run: echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc then open a new terminal or run: source ~/.zshrc
…even when $HOME/.local/bin is definitively in $PATH. The warning also cannot be silenced via DISABLE_INSTALLATION_CHECKS=1.
Environment
- macOS 26.3 (Darwin 25.3.0, arm64)
- zsh 5.9
- Claude Code 2.1.139 (native install)
installMethod: nativein~/.claude.json- Binary build:
VERSION:"2.1.139",BUILD_TIME:"2026-05-11T17:03:24Z",GIT_SHA:"208bf4b44f987c4c62618ae20ce1715d53693c62"
Reproduction
Run with PATH explicitly set so ~/.local/bin is the first entry and provably present:
$ PATH="/Users/greg/.local/bin:/usr/bin:/bin" /Users/greg/.local/bin/claude update
Current version: 2.1.139
Checking for updates to latest version...
Warning: Native installation exists but ~/.local/bin is not in your PATH
Fix: Run: echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc then open a new terminal or run: source ~/.zshrc
Claude Code is up to date (2.1.139)
which claude in the same shell correctly resolves to /Users/greg/.local/bin/claude. The directory is there. The binary itself is there. The warning is wrong.
Expected
The warning should only fire when ~/.local/bin is truly missing from $PATH. With the PATH shown above, no warning should appear.
Evidence the PATH check logic itself is fine — it's the binary that's broken
Re-implementing the check in plain Node (logic extracted from strings of ~/.local/share/claude/versions/2.1.139):
const path = require('path');
const os = require('os');
const target = path.join(os.homedir(), '.local', 'bin'); // /Users/greg/.local/bin
const found = (process.env.PATH || '').split(path.delimiter).some(j => {
const M = j.replace(/\/+$/, '');
return M === target;
});
console.log(found); // → true
So the algorithm, run from stock Node with the same PATH, returns true. The same algorithm bundled into the claude binary returns false. Likely culprits: Bun-compiled path.resolve / path.delimiter behaving differently than Node, or process.env.PATH being mutated somewhere before the check runs.
Workarounds tried (none worked)
- Ensuring
~/.local/binis first in$PATH - Multiple explicit
export PATH="$HOME/.local/bin:$PATH"in~/.zshrc - Sourcing
~/.local/bin/env(the standard idempotent snippet) DISABLE_INSTALLATION_CHECKS=1 claude updateinstallMethod: nativealready set in~/.claude.json
The warning is cosmetic (claude works fine), but it incorrectly tells users to modify their shell config when nothing is actually wrong with their PATH.
This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗