The official docs tell you how Claude Code works when it works. This is the other document. What to do when it does not.
Every error below is one I have actually hit or been sent by someone else, across macOS, Windows, WSL, and CI. They are ordered roughly by how often they come up. Each one gets the same treatment. What the error actually means, how to confirm that diagnosis rather than guessing, and the fix.
If you are setting up for the first time and nothing is broken yet, start with the full setup guide instead.
Table of Contents
- command not found: claude
- script not found stream-json
- Process exited with code 1
- Authentication fails or loops
- API Error 529: Overloaded
- HTTP 400 tool use concurrency errors
- Permission denied on macOS
- Windows Defender blocks the install
- WSL: works in one shell, not the other
- claude doctor hangs at 100% CPU
- Sessions get slower and slower
- Claude ignores CLAUDE.md
- MCP server fails to start
- How to remove Claude Code completely
- The nuclear reset
command not found: claude
The single most common one, and almost always a PATH problem rather than a failed install.
What it means. The binary installed successfully. Your shell does not know where to look for it.
Confirm the diagnosis first. Do not reinstall until you have checked whether the file exists:
# macOS / Linux / WSL
ls -la ~/.local/bin/claude
# Windows PowerShell
Test-Path "$env:USERPROFILE\.local\bin\claude.exe"
If that returns the file or True, the install is fine and this is purely PATH.
Fix 1: restart the terminal. The installer appends to your shell profile, but your current session was started before that happened. Closing and reopening the terminal resolves this more often than anything else, and costs nothing to try first.
Fix 2: add it to PATH yourself. If a fresh terminal still cannot find it, the installer either did not write to your profile or wrote to a profile your shell does not read:
# zsh (macOS default since Catalina)
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
# bash
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
The trap here is editing the wrong file. macOS ships zsh, and a lot of guidance still says .bashrc. Check which shell you are actually in with echo $SHELL before you edit anything.
Fix 3: confirm the PATH took.
echo $PATH | tr ':' '\n' | grep -q "$HOME/.local/bin" && echo "on PATH" || echo "NOT on PATH"
which claude
If you installed via Homebrew and the binary is missing entirely, Homebrew put it somewhere else. brew --prefix tells you where, and on Apple Silicon that is /opt/homebrew rather than /usr/local: a directory that is not on the default PATH for shells configured before the machine was migrated.
script not found stream-json
Full error text: process exited with code 1, error: script not found "stream-json".
What it means. Something between you and Claude Code consumed the --output-format stream-json argument and tried to interpret stream-json as its own subcommand or script name. Claude Code never received the flag.
The word script is the tell. That is a package-manager vocabulary word, not a Claude Code one.
The usual cause is argument forwarding through a package manager. When you run something like:
npm run claude -- -p "review this" --output-format stream-json
everything after the first -- is supposed to be forwarded, but a second unquoted separator, a missing one, or a wrapper script that re-splits arguments will hand stream-json back to npm as a script name. npm then looks for a script by that name in package.json, does not find one, and emits exactly this error.
Confirm it. Run the same command directly, with no wrapper:
claude -p "test" --output-format stream-json --verbose
If that works and the wrapped version does not, the wrapper is the problem and Claude Code is fine.
Fixes, in order of preference:
- Call the
claudebinary directly in scripts and CI rather than throughnpm run. It removes an entire class of argument-mangling bug. - If you must go through a package manager, quote the whole thing and check exactly one
--separator is present. - In CI, echo the fully expanded command before running it. Most of these bugs are visible the moment you can see what actually got executed.
Related gotcha: --output-format stream-json also expects --verbose when combined with -p in headless mode. If you get past the script-not-found error and hit a complaint about the format, add --verbose.
Process exited with code 1
Exit code 1 is a generic failure, so on its own it tells you nothing. The message printed alongside it is the actual error, and it is usually one of the specific cases in this post.
Get the real error. Run the command outside whatever is swallowing the output:
claude --version
claude doctor
If both work, Claude Code itself is healthy and the failure is in how it is being invoked: a wrapper, a CI step, a hook, or an argument that never arrived.
In CI specifically, exit code 1 with no visible message almost always means the process needed a TTY and did not have one. Headless usage needs -p (print mode); interactive mode in a non-interactive runner fails immediately.
Authentication fails or loops
Check the subscription first. Claude Code requires an active paid plan. Free accounts do not include it, and the failure presents as an auth error rather than a billing message, which sends people down the wrong path entirely.
The single most common cause after that is a stray API key:
echo $ANTHROPIC_API_KEY
If that prints anything, it is overriding your subscription authentication. Unset it and retry:
unset ANTHROPIC_API_KEY
claude
Then find where it is being set: usually .zshrc, .bashrc, or a .env file being sourced, and remove it, or the problem returns on the next new terminal.
If the browser redirect fails, log in at claude.ai in your default browser first, then run claude again. The OAuth flow assumes an existing session.
On a corporate network, OAuth is frequently blocked. claude.ai and anthropic.com need to be allowed. If you get a redirect that hangs rather than an error, that is what it looks like from behind a filtering proxy.
Check state directly:
claude auth status
API Error 529: Overloaded
What it means. Anthropic's servers are at capacity. This is not your configuration, your network, or your account.
What to do. Wait and retry. There is no client-side fix, and reinstalling will not help.
What to do in automation: retry with exponential backoff and jitter, and cap the attempts. A retry loop with no backoff makes a capacity problem worse for everyone including you, and an uncapped one is how you get a surprising bill. Every retry is billed. If you run agents unattended, model the failure path with the agent loop cost predictor before you set the cap.
HTTP 400 tool use concurrency errors
What it means. The conversation state is internally inconsistent, typically a tool call recorded without its matching result, which the API rejects on the next turn. Once it happens, every subsequent message in that session fails the same way.
The fix:
/rewind
That rolls back to the last good state. Continuing to send messages will not clear it, and neither will /clear in every case, because the broken exchange stays in history.
If /rewind does not recover it, start a fresh session. The state is per-conversation, so a new one is clean.
Permission denied on macOS
chmod +x ~/.local/bin/claude
If it persists, macOS Gatekeeper may have quarantined the binary:
xattr -d com.apple.quarantine ~/.local/bin/claude
That is the correct fix for a binary you downloaded deliberately from a source you trust. It is not a fix to apply reflexively to anything that will not run.
Windows Defender blocks the install
Defender heuristics flag the installer often enough that you should expect it rather than debug it. The symptom is an install that appears to succeed and produces no binary.
Add an exclusion: Windows Security → Virus & Threat Protection → Manage Settings → Exclusions → Add an exclusion → Folder, then select:
%USERPROFILE%\.local\bin\
Then reinstall. Adding the exclusion after the fact does not restore a file Defender already removed.
WSL: works in one shell, not the other
This one confuses people for longer than it should, and the cause is simple: WSL and Windows are separate environments with separate PATHs and separate installs.
Installing Claude Code in PowerShell does not install it in WSL. Installing it in WSL does not install it in PowerShell. If it works in one and not the other, that is the expected behavior, not a bug.
Decide which one you actually want. For most development work on Windows, WSL is the better environment: the tooling Claude Code shells out to (git, node, standard Unix utilities) behaves the way every guide assumes. Install it inside WSL and run it from there.
The related trap is path translation. A WSL-installed Claude Code sees /home/you/project, not C:\Users\you\project. Working on files stored on the Windows filesystem from inside WSL also carries a real performance penalty across the /mnt/c boundary. Keep repositories inside the WSL filesystem if you can.
claude doctor hangs at 100% CPU
A known failure mode rather than a misconfiguration. claude doctor can spin without completing.
Kill it with Ctrl+C, restart your terminal, and try once more. If it hangs again, skip it. It is a diagnostic tool, and the checks it performs (binary present, PATH correct, auth valid) can all be done manually with claude --version, which claude, and claude auth status.
Sessions get slower and slower
Two separate causes that present identically.
Context growth. Every turn resends the conversation so far, so a long session gets slower and more expensive as it goes. This is inherent, not a bug. Start a new session for a new task rather than continuing one indefinitely, and use /compact when a long session is still useful but has accumulated material you no longer need.
.claude.json bloat. This file accumulates session history and can grow large enough to slow startup noticeably. Check it:
du -h ~/.claude.json
If it is tens of megabytes, back it up and truncate it:
cp ~/.claude.json ~/.claude.json.backup
echo '{}' > ~/.claude.json
You lose session history. You do not lose settings in ~/.claude/ or your project files.
If you want to know what is actually consuming context rather than guessing, the context auditor breaks it down by source.
Claude ignores CLAUDE.md
Usually one of three things, in this order of likelihood.
It is not where you think it is. CLAUDE.md is read from the project root: the directory you launched claude from. Launched from a subdirectory, the root file may not be picked up. Confirm with pwd before assuming the file is being ignored.
It contains contradictory instructions. Two rules that cannot both be satisfied get resolved somehow, and the resolution looks like disobedience. "Be concise" alongside "always explain your reasoning fully" is a real example of this. The system prompt analyzer finds conflicting pairs.
It is too long. A file that has grown by accretion to several thousand tokens dilutes every instruction in it, and costs those tokens on every single turn. The rule worth applying to each line: can you name a specific mistake it has prevented? If not, delete it. The AGENTS.md bloat linter measures this if you would rather have a number than an opinion.
MCP server fails to start
Three causes cover nearly all of these.
Relative command path. The MCP launcher does not inherit your interactive shell's PATH, so a bare command name that works in your terminal frequently fails in the config. Use an absolute path to the binary:
which node # use the full path this prints
Trailing comma in the JSON. It fails silently, and the symptom is a server that simply does not appear rather than an error message. Run the file through a JSON validator before debugging anything else.
Missing environment variables. A variable set in .zshrc is not visible to the server process. It has to be declared in the MCP config's env block.
The MCP config builder generates the structure correctly if you would rather not hand-write it.
How to remove Claude Code completely
Covering both the binary and the configuration, since "uninstall" usually means both.
macOS, Linux, and WSL:
# The binary
rm -f ~/.local/bin/claude
rm -rf ~/.local/share/claude
# Settings, memory, and session history
rm -rf ~/.claude
rm -f ~/.claude.json
Windows PowerShell:
Remove-Item -Path "$env:USERPROFILE\.local\bin\claude.exe" -Force
Remove-Item -Path "$env:USERPROFILE\.local\share\claude" -Recurse -Force
Remove-Item -Path "$env:USERPROFILE\.claude" -Recurse -Force
Remove-Item -Path "$env:USERPROFILE\.claude.json" -Force
If you installed through a package manager, use it to uninstall instead, or you will leave the manager's records inconsistent:
brew uninstall --cask claude-code # Homebrew
winget uninstall Anthropic.ClaudeCode # WinGet
Two things to know before you do this.
Removing ~/.claude deletes your custom commands, hooks, and any skills you have written. Back the directory up first if there is anything in it you would miss. Reinstalling does not bring it back.
And per-project CLAUDE.md files live in your repositories, not in ~/.claude. Uninstalling does not touch them, which is usually what you want.
On Windows, remember WSL is separate. Removing it from PowerShell leaves any WSL install untouched, and vice versa. If you installed in both, remove it in both.
The nuclear reset
When you want a genuinely clean install rather than a repair:
# Remove everything
rm -f ~/.local/bin/claude
rm -rf ~/.local/share/claude
rm -rf ~/.claude
rm -f ~/.claude.json
# Reinstall
curl -fsSL https://claude.ai/install.sh | bash
claude --version
Remove-Item -Path "$env:USERPROFILE\.local\bin\claude.exe" -Force
Remove-Item -Path "$env:USERPROFILE\.local\share\claude" -Recurse -Force
Remove-Item -Path "$env:USERPROFILE\.claude" -Recurse -Force
Remove-Item -Path "$env:USERPROFILE\.claude.json" -Force
irm https://claude.ai/install.ps1 | iex
Back up ~/.claude first if it contains hooks, commands, or skills you wrote.
The general diagnostic order
When something breaks and it is not on this list, this sequence isolates the layer faster than guessing:
claude --version: if this fails, it is install or PATH, nothing else.claude auth status: if this fails, it is authentication, and no amount of reinstalling fixes an auth problem.claudein a scratch directory with no CLAUDE.md: if it works here and not in your project, the problem is project configuration, not Claude Code.- Disable your hooks: a hook that exits non-zero blocks every tool call and makes the agent look broken. This is a common self-inflicted wound and an easy one to miss, because the hook is working exactly as written.
- Only then reinstall. It is the least likely fix and the most disruptive, and it destroys the evidence you would need to diagnose a recurrence.
Related reading
- The definitive Claude Code setup guide for Windows and macOS: installation, authentication, models, and configuration from scratch
- Seven Claude Code hooks that act as guardrails: including how to write hooks that fail safely
- How to write a CLAUDE.md that earns its tokens
- Claude Code context auditor: find what is silently consuming your context window