Fix zsh: command not found: claude (2026)
The Error
zsh: command not found: claude
Or in bash:
bash: claude: command not found
This error means your shell cannot find the claude executable in any directory listed in your $PATH. The Claude Code CLI is either not installed, installed in a non-standard location, or your shell configuration is missing the correct PATH entry.
Cause 1: Claude Code Is Not Installed
The most common cause. Claude Code is an npm package that must be installed globally.
Fix:
npm install -g @anthropic-ai/claude-code
Verify the installation:
which claude && claude --version
Expected output:
/usr/local/bin/claude # or ~/.npm-global/bin/claude
claude-code 1.x.x
If npm install -g fails with a permission error, do not use sudo. See Cause 6 below.
Cause 2: Wrong Node.js Version
Claude Code requires Node.js 18 or later. Older versions will either fail to install the package or install it in an incompatible state.
Diagnose:
node --version
If the output shows v16.x.x or lower, you need to upgrade.
Fix:
# Using nvm (recommended)
nvm install 22
nvm use 22
nvm alias default 22
# Verify
node --version
# Expected: v22.x.x
# Now install Claude Code
npm install -g @anthropic-ai/claude-code
If you do not have nvm installed:
# Install nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
# Reload shell
source ~/.zshrc
# Install Node 22
nvm install 22
On macOS, if you installed Node through Homebrew:
brew update && brew upgrade node
Cause 3: npm Global Bin Directory Not in PATH
npm installs global packages in a directory that may not be in your shell's PATH. This is the second most common cause of the error.
Diagnose:
# Where does npm put global binaries?
npm config get prefix
# Is that directory's bin/ in your PATH?
echo $PATH | tr ':' '\n' | grep "$(npm config get prefix)"
If the grep returns nothing, the npm bin directory is not in your PATH.
Fix:
# Get the npm prefix
NPM_PREFIX=$(npm config get prefix)
# Add to PATH for the current session
export PATH="$NPM_PREFIX/bin:$PATH"
# Verify it works now
which claude
Then make it permanent (see the shell-specific sections below).
Cause 4: Installed with a Different Package Manager
If you installed Claude Code with yarn or pnpm instead of npm, the binary is in a different location.
Diagnose:
# Check all possible locations
ls -la $(npm config get prefix)/bin/claude 2>/dev/null
ls -la $(yarn global bin 2>/dev/null)/claude 2>/dev/null
ls -la $(pnpm bin -g 2>/dev/null)/claude 2>/dev/null
Fix for yarn:
# Find yarn's global bin
yarn global bin
# Example output: /Users/you/.yarn/bin
# Add to PATH
export PATH="$(yarn global bin):$PATH"
Fix for pnpm:
# Find pnpm's global bin
pnpm bin -g
# Example output: /Users/you/Library/pnpm
# Add to PATH
export PATH="$(pnpm bin -g):$PATH"
Recommended approach: Uninstall from yarn/pnpm and reinstall with npm for consistency:
yarn global remove @anthropic-ai/claude-code 2>/dev/null
pnpm remove -g @anthropic-ai/claude-code 2>/dev/null
npm install -g @anthropic-ai/claude-code
Cause 5: Shell Configuration Not Sourced
You added the PATH export to your shell config file, but the current terminal session is using an older environment that does not include it.
Diagnose:
# Check if your shell config has the PATH entry
grep -n "claude\|npm.*bin\|NPM_PREFIX" ~/.zshrc ~/.bashrc ~/.bash_profile 2>/dev/null
Fix:
# Reload your shell configuration
source ~/.zshrc # for zsh
source ~/.bashrc # for bash
# Or simply open a new terminal window
If the PATH entry is missing from your config file entirely, add it:
# For zsh (default on macOS)
echo 'export PATH="$(npm config get prefix)/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
# For bash
echo 'export PATH="$(npm config get prefix)/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
Cause 6: macOS Permission Issues with /usr/local
On macOS, npm's default global prefix is /usr/local, which requires elevated permissions. If you ran sudo npm install -g in the past, the /usr/local/lib/node_modules directory may be owned by root, causing future non-sudo installs to fail silently.
Diagnose:
ls -la /usr/local/lib/node_modules/ | head -5
# If you see "root" as the owner, permissions are wrong
npm install -g @anthropic-ai/claude-code 2>&1
# Look for EACCES errors
Fix (Option A -- change npm prefix to a user-owned directory):
# Create a directory for global packages
mkdir -p ~/.npm-global
# Configure npm to use it
npm config set prefix ~/.npm-global
# Add to PATH
echo 'export PATH="$HOME/.npm-global/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
# Now install without sudo
npm install -g @anthropic-ai/claude-code
Fix (Option B -- fix ownership of /usr/local):
sudo chown -R $(whoami) /usr/local/lib/node_modules
sudo chown -R $(whoami) /usr/local/bin
npm install -g @anthropic-ai/claude-code
Option A is safer because it avoids touching system directories. Option B works if you are the only user on the machine.
Never use sudo npm install -g. It creates root-owned files in your global node_modules, which causes cascading permission problems for every future global install.
Shell-Specific Permanent PATH Fixes
zsh (default on macOS)
# Edit your zsh config
nano ~/.zshrc
# Add this line at the end:
export PATH="$(npm config get prefix)/bin:$PATH"
# If using nvm, make sure the nvm block loads first:
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
export PATH="$(npm config get prefix)/bin:$PATH"
# Save and reload
source ~/.zshrc
bash
# On macOS, bash reads ~/.bash_profile for login shells
echo 'export PATH="$(npm config get prefix)/bin:$PATH"' >> ~/.bash_profile
source ~/.bash_profile
# On Linux, bash reads ~/.bashrc for interactive shells
echo 'export PATH="$(npm config get prefix)/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
fish
# Fish uses a different syntax
set -Ux fish_user_paths (npm config get prefix)/bin $fish_user_paths
# Verify
which claude
Complete Diagnostic Script
Run this to identify exactly what is wrong:
echo "=== Node.js ==="
which node && node --version || echo "Node.js NOT FOUND"
echo ""
echo "=== npm ==="
which npm && npm --version || echo "npm NOT FOUND"
echo ""
echo "=== npm global prefix ==="
npm config get prefix 2>/dev/null || echo "Cannot determine npm prefix"
echo ""
echo "=== Claude Code installed? ==="
npm list -g @anthropic-ai/claude-code 2>/dev/null || echo "Claude Code NOT installed globally"
echo ""
echo "=== Claude binary location ==="
find "$(npm config get prefix 2>/dev/null)/bin" -name "claude" 2>/dev/null || echo "claude binary not found in npm bin"
echo ""
echo "=== PATH contains npm bin? ==="
NPM_BIN="$(npm config get prefix 2>/dev/null)/bin"
echo "$PATH" | tr ':' '\n' | grep -q "$NPM_BIN" && echo "YES: $NPM_BIN is in PATH" || echo "NO: $NPM_BIN is NOT in PATH"
echo ""
echo "=== Shell ==="
echo "$SHELL"
echo "Config files:"
ls -la ~/.zshrc ~/.bashrc ~/.bash_profile 2>/dev/null
This script tells you exactly which cause applies to your situation. Fix the identified issue using the corresponding section above.
These diagnostic steps are from The Claude Code Playbook — 200 production-ready templates including error prevention rules and CLAUDE.md configs tested across 50+ project types.
Universal Shell Installer Script
Instead of manually adapting installation steps for your specific shell, use this script that detects your shell type, installs Claude Code, configures PATH, and verifies everything works. It handles zsh, bash, and fish on macOS and Linux.
#!/bin/bash
# install-claude-code.sh — Universal Claude Code installer for any shell
# Works on: macOS (zsh/bash), Linux (bash/zsh/fish), WSL (bash)
set -uo pipefail
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
NC='\033[0m'
echo "=== Claude Code Universal Installer ==="
echo ""
# 1. Detect current shell
CURRENT_SHELL=$(basename "$SHELL")
echo -e "Detected shell: ${GREEN}$CURRENT_SHELL${NC}"
# 2. Check Node.js
echo -n "Checking Node.js... "
if ! command -v node &>/dev/null; then
echo -e "${RED}NOT FOUND${NC}"
echo "Installing Node.js via nvm..."
if ! command -v nvm &>/dev/null; then
curl -so- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
fi
nvm install 22
nvm use 22
nvm alias default 22
echo -e "${GREEN}Node.js $(node --version) installed${NC}"
else
NODE_MAJOR=$(node --version | sed 's/v//' | cut -d. -f1)
if [ "$NODE_MAJOR" -lt 18 ]; then
echo -e "${YELLOW}$(node --version) — upgrading to 22${NC}"
if command -v nvm &>/dev/null; then
nvm install 22 && nvm use 22 && nvm alias default 22
else
echo -e "${RED}Node.js 18+ required. Install nvm or upgrade Node manually.${NC}"
exit 1
fi
else
echo -e "${GREEN}$(node --version)${NC}"
fi
fi
# 3. Configure npm prefix to avoid permission issues
echo -n "Configuring npm prefix... "
NPM_PREFIX=$(npm config get prefix 2>/dev/null)
if [ "$NPM_PREFIX" = "/usr/local" ] || [ "$NPM_PREFIX" = "/usr" ]; then
mkdir -p "$HOME/.npm-global"
npm config set prefix "$HOME/.npm-global"
NPM_PREFIX="$HOME/.npm-global"
echo -e "${GREEN}Set to $NPM_PREFIX (avoids sudo)${NC}"
else
echo -e "${GREEN}$NPM_PREFIX${NC}"
fi
NPM_BIN="$NPM_PREFIX/bin"
# 4. Install Claude Code
echo -n "Installing Claude Code... "
if npm install -g @anthropic-ai/claude-code 2>/dev/null; then
echo -e "${GREEN}DONE${NC}"
else
echo -e "${RED}FAILED${NC}"
echo "Trying with clean cache..."
npm cache clean --force 2>/dev/null
npm install -g @anthropic-ai/claude-code
fi
# 5. Add to PATH based on detected shell
echo -n "Configuring PATH for $CURRENT_SHELL... "
add_to_path() {
local config_file="$1"
local path_line="$2"
if [ -f "$config_file" ] && grep -qF "$NPM_BIN" "$config_file" 2>/dev/null; then
echo -e "${GREEN}Already configured in $config_file${NC}"
else
echo "" >> "$config_file"
echo "$path_line" >> "$config_file"
echo -e "${GREEN}Added to $config_file${NC}"
fi
}
case "$CURRENT_SHELL" in
zsh)
add_to_path "$HOME/.zshrc" "export PATH=\"$NPM_BIN:\$PATH\""
export PATH="$NPM_BIN:$PATH"
;;
bash)
# macOS uses .bash_profile, Linux uses .bashrc
if [ "$(uname)" = "Darwin" ]; then
add_to_path "$HOME/.bash_profile" "export PATH=\"$NPM_BIN:\$PATH\""
else
add_to_path "$HOME/.bashrc" "export PATH=\"$NPM_BIN:\$PATH\""
fi
export PATH="$NPM_BIN:$PATH"
;;
fish)
FISH_CONFIG="$HOME/.config/fish/config.fish"
mkdir -p "$(dirname "$FISH_CONFIG")"
if [ -f "$FISH_CONFIG" ] && grep -qF "$NPM_BIN" "$FISH_CONFIG" 2>/dev/null; then
echo -e "${GREEN}Already configured in $FISH_CONFIG${NC}"
else
echo "" >> "$FISH_CONFIG"
echo "set -gx PATH $NPM_BIN \$PATH" >> "$FISH_CONFIG"
echo -e "${GREEN}Added to $FISH_CONFIG${NC}"
fi
export PATH="$NPM_BIN:$PATH"
;;
*)
echo -e "${YELLOW}Unknown shell: $CURRENT_SHELL${NC}"
echo " Manually add $NPM_BIN to your PATH"
export PATH="$NPM_BIN:$PATH"
;;
esac
# 6. Verify installation
echo ""
echo "=== Verification ==="
echo -n "claude binary: "
if CLAUDE_PATH=$(which claude 2>/dev/null); then
echo -e "${GREEN}$CLAUDE_PATH${NC}"
else
echo -e "${RED}NOT FOUND — open a new terminal and try again${NC}"
exit 1
fi
echo -n "claude version: "
if CLAUDE_VER=$(claude --version 2>/dev/null); then
echo -e "${GREEN}$CLAUDE_VER${NC}"
else
echo -e "${RED}FAILED TO RUN${NC}"
exit 1
fi
echo ""
echo -e "${GREEN}Claude Code installed successfully.${NC}"
echo ""
echo "Next steps:"
echo " 1. Open a new terminal window (or run: source ~/.${CURRENT_SHELL}rc)"
echo " 2. Set your API key: export ANTHROPIC_API_KEY='sk-ant-...'"
echo " 3. Run: claude"
Save this script as install-claude-code.sh, make it executable with chmod +x install-claude-code.sh, and run it. The script handles every shell-specific difference automatically: zsh users get their ~/.zshrc updated, bash users get ~/.bashrc or ~/.bash_profile (depending on OS), and fish users get ~/.config/fish/config.fish configured. The script also sets the npm prefix to a user-owned directory to prevent the permission issues that cause the majority of "command not found" errors after installation.
Verifying the Fix
After applying any fix, run this verification sequence:
# 1. Check the binary is found
which claude
# Expected: a path like /usr/local/bin/claude or ~/.npm-global/bin/claude
# 2. Check the version
claude --version
# Expected: claude-code followed by a version number
# 3. Run a quick test
claude -p "Say hello"
# Expected: A response from Claude
If which claude still returns nothing after following the steps above, open a brand new terminal window (not a new tab in the same window). Some terminal emulators cache the PATH from the session that spawned them.
FAQ
I installed Claude Code but it only works in one terminal window. Why?
You added the PATH export to the current session with export PATH=... but did not add it to your shell configuration file (~/.zshrc or ~/.bashrc). The fix applies only to the terminal where you ran it. Add the export line to your config file and source it.
Should I use sudo to install Claude Code globally?
No. Using sudo npm install -g creates root-owned files that break future installs. Instead, change your npm prefix to a user-owned directory (see Cause 6, Option A).
I use nvm and the error comes back after switching Node versions.
nvm installs global packages per Node version. When you switch versions with nvm use, you lose packages installed under the previous version. Reinstall after switching: nvm use 22 && npm install -g @anthropic-ai/claude-code.
Does Claude Code work on Windows?
Claude Code requires macOS or Linux (including WSL on Windows). It does not run natively on Windows outside of WSL. In WSL, the error would show as bash: claude: command not found and the same PATH fixes apply.
The install succeeded but which claude shows a different path than expected. Is that a problem?
Not necessarily. As long as which claude returns a valid path and claude --version outputs a version number, the installation is correct. Different paths occur depending on whether you use nvm, Homebrew, or a custom npm prefix.
I see ENOENT errors during installation. What does that mean?
ENOENT means a file or directory was not found during the install process. This usually indicates a corrupted npm cache. Fix it with: npm cache clean --force && npm install -g @anthropic-ai/claude-code.
Can I install Claude Code with yarn or pnpm instead of npm?
Yes, but the binary will be in a different location. You need to ensure that package manager's global bin directory is in your PATH. For consistency, npm is recommended. If you already installed with yarn or pnpm, uninstall and reinstall with npm.
Why does the error come back after restarting my computer?
You likely added the PATH export to the current session but not to your shell configuration file (~/.zshrc or ~/.bashrc). Add the export line to your config file so it loads automatically on every new shell session.
Does Claude Code work in fish shell?
Yes. Fish uses a different syntax for PATH configuration. Use set -Ux fish_user_paths (npm config get prefix)/bin $fish_user_paths to add the npm bin directory to your PATH permanently.
I installed Node.js with Homebrew but claude command is not found. What should I do?
Homebrew installs Node.js in /opt/homebrew/bin on Apple Silicon Macs or /usr/local/bin on Intel Macs. Verify the path with npm config get prefix and ensure the resulting bin directory is in your PATH. Run brew link node if the symlinks are missing.
I hit this exact error six months ago. Then I wrote a CLAUDE.md that tells Claude my stack, my conventions, and my error handling patterns. Haven't seen it since.
I run 5 Claude Max subs, 16 Chrome extensions serving 50K users, and bill $500K+ on Upwork. These CLAUDE.md templates are what I actually use.