claude update: false-positive "~/.local/bin is not in your PATH" warning when it actually is

Resolved 💬 5 comments Opened May 12, 2026 by gjkochan Closed Jul 6, 2026

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: native in ~/.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/bin is 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 update
  • installMethod: native already 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.

View original on GitHub ↗

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