Step-by-step fixes for the most common Claude Code errors, slowdowns, and configuration issues.
Jump to your problem above, or scan the error messages table if you have a specific error string. Most issues fall into one of three root causes: credentials, context size, or permissions.
AuthenticationError: invalid x-api-key401 Unauthorized
claude config get api_key and compare the last 4 characters.claude config set api_key sk-ant-...ANTHROPIC_API_KEY environment variable, that overrides the config file — check with echo $ANTHROPIC_API_KEY.Common trap: copying an API key from a web page can add a leading/trailing newline. Always paste into a plain text editor first, strip whitespace, then set it.
IDE extensions (VS Code, JetBrains) read credentials from a different location than the CLI. Run claude auth status in a terminal opened from the IDE. If the terminal shows a different user than the web UI, log in again: claude auth logout && claude auth login.
RateLimitError: You have exceeded your rate limit
claude-haiku-4-5-20251001 for exploratory work — it has a higher RPM quota on most tiers.Insufficient quota / billing limit reached
Check your usage and limits at console.anthropic.com → Usage. If you've hit a prepaid credit limit, add more credits. If you're on a subscription, check monthly spend limits. Claude Code's pricing page has a full breakdown of what each request type costs.
command not found: claudezsh: command not found: claude
npm list -g @anthropic-ai/claude-codenpm install -g @anthropic-ai/claude-codenpm bin -g → should be in your $PATH.export PATH="$(npm bin -g):$PATH" then source ~/.zshrc.npm error EACCES: permission denied, mkdir '/usr/local/lib/node_modules'
Don't use sudo with npm. Instead, configure npm to use a user-local prefix:
mkdir -p ~/.npm-global
npm config set prefix '~/.npm-global'
echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
npm install -g @anthropic-ai/claude-code
Or use a Node version manager (nvm, fnm, volta) — they install to your home dir and avoid permission issues entirely.
npm update -g @anthropic-ai/claude-code
claude --version
If the version still doesn't change, the old binary may be cached in a different location. Find it: which claude — if the path doesn't match your npm global bin, uninstall and reinstall:
npm uninstall -g @anthropic-ai/claude-code
npm install -g @anthropic-ai/claude-code
This applies to the desktop app, not the npm package. Right-click the app → Open → Open anyway. Or run: xattr -dr com.apple.quarantine /Applications/Claude\ Code.app.
| Cause | Diagnosis | Fix |
|---|---|---|
| Large context window | claude --debug shows token count >50K | /compact or start fresh session |
| Wrong model | claude config get model shows opus | Switch to sonnet or haiku for simple tasks |
| Network latency | Ping api.anthropic.com >200ms | Use a VPN to a US server, or accept latency |
| Reading huge files | Claude reads node_modules or dist/ | Add .claudeignore |
| API outage | Errors across all requests | Check status.anthropic.com |
Press Ctrl+C to interrupt. Then:
claude --debug <same request> to see verbose logs — look for where it's blocked.claude mcp remove <name>) to identify if an MCP server is hanging during connection.PreToolUse hooks in .claude/settings.json that run commands with infinite loops or wait for input.Claude re-reads files whose content might change between turns. To stop this, add stable large files to .claudeignore (same syntax as .gitignore):
# .claudeignore
node_modules/
dist/
build/
*.lock
*.log
coverage/
.next/
Claude will still know these paths exist (from ls), but won't read their contents unless you explicitly ask.
ContextLengthExceeded: The request body exceeded the maximum context length
/compact — compresses older conversation turns without losing key facts./clear..claudeignore to prevent large files from being read into context.--no-auto-read flag to prevent auto-reading directory contents on launch.The 200K token limit for claude-sonnet-4-6 is roughly 500–600KB of combined text (source files + conversation). A large React codebase with 100 files averages 50–80KB — well within limits unless Claude reads all of them in one session.
This is a compaction side-effect, not a bug. When /compact runs (automatically or manually), it summarizes old turns. Details that seemed minor may get dropped. Strategies:
Check the following:
CLAUDE.md (case-sensitive on Linux/macOS).claude, not a subdirectory.claude --print-config to confirm it's being loaded.Permanently allow a tool or command pattern in .claude/settings.json:
{
"allowedTools": [
"Read",
"Glob",
"Grep",
{"name": "Bash", "allowedCommands": ["npm test", "npm run build", "git status", "git diff"]}
]
}
Or use the /permissions command in Claude Code to add rules interactively. See the full permissions guide for project vs. global settings.
Claude Code's defaults are conservative around destructive operations. To allow file deletion:
{
"allowedTools": [
{"name": "Bash", "allowedCommands": ["rm -f src/old-module.ts"]}
]
}
For broad file deletion in a specific directory, consider using a script that Claude can call instead of raw rm commands — this gives you a clear audit trail.
If Claude tries to run a script but gets permission denied:
# Claude can run this to fix it
chmod +x scripts/deploy.sh
Or add a Make target that Claude can call without needing chmod. Pre-chmod your script files once, then add them to your allowed Bash commands list.
This is intentional — Claude Code does not auto-push or force-push by default. To allow git operations:
{
"allowedTools": [
{"name": "Bash", "allowedCommands": ["git add", "git commit", "git push origin"]}
]
}
git push --force to allowedCommands for a shared branch. This bypasses history protection.
claude mcp list — shows each server and its status (connected / error).claude mcp test <server-name>~/.claude/mcp_settings.json and run it directly in a terminal. Watch stderr for startup errors.which <server-binary> or node <server-path>.claude mcp remove <name> && claude mcp add <name> <command>.Common causes: missing environment variables, wrong Node.js version, missing npm packages. Check:
# Run the server manually with verbose output
node /path/to/mcp-server/index.js 2>&1
If it requires environment variables (API keys, DB URLs), add them to the env field in mcp_settings.json:
{
"mcpServers": {
"my-db": {
"command": "node",
"args": ["/path/to/server.js"],
"env": {"DATABASE_URL": "postgres://..."}
}
}
}
After the server connects, tool call errors usually mean the server received valid JSON but its internal logic failed. Enable debug logging in the MCP server itself (check its README), then watch the server's stderr while Claude makes a tool call. The error will be in the server process, not in Claude Code.
Claude Code may launch the server with a different working directory or PATH. In mcp_settings.json, set cwd explicitly:
{
"mcpServers": {
"my-server": {
"command": "/usr/local/bin/node",
"args": ["/absolute/path/to/server.js"],
"cwd": "/absolute/path/to/server/"
}
}
}
Check placement in .claude/settings.json:
{
"hooks": {
"PreToolUse": [
{"matcher": "Bash", "hooks": [{"type": "command", "command": "echo 'pre-bash hook'"}]}
]
}
}
Verify: (1) The event name matches exactly (PreToolUse, PostToolUse, PreCompact, Stop); (2) The matcher matches the tool name Claude is calling; (3) The JSON is valid (run jq . .claude/settings.json).
If a PreToolUse hook exits with a non-zero code, Claude treats it as a permission denial and won't call the tool. Run the hook command manually to see what it's returning. Temporarily disable it:
# Comment out the hook entry in settings.json to disable
# { "type": "command", "command": "..." } ← disable by removing or commenting
Hooks communicate with Claude via stdout (structured JSON). If a hook writes to stderr or doesn't emit JSON, Claude won't see it. Format your hook output:
#!/bin/bash
# Example PreToolUse hook that adds context
echo '{"type":"context","content":"Current git branch: '$(git rev-parse --abbrev-ref HEAD)'"}'
See the full hooks guide for all output formats.
| Error | Root cause | Quick fix |
|---|---|---|
401 invalid x-api-key |
Wrong or revoked API key | claude config set api_key <key> |
429 rate_limit_exceeded |
Too many requests / quota exhausted | Wait and retry; upgrade tier |
ContextLengthExceeded |
Prompt + history > 200K tokens | /compact then retry |
command not found: claude |
npm global bin not in PATH | Add npm bin dir to PATH |
EACCES permission denied |
npm install needs sudo (don't) | Use nvm or fix npm prefix |
Tool call blocked by permission system |
Tool not in allowedTools | Add to settings.json allowedTools |
MCP server failed to start |
Binary missing or env var unset | Run server manually to see error |
Cannot read properties of undefined |
Stale Claude Code version bug | npm update -g @anthropic-ai/claude-code |
Connection refused (MCP) |
MCP server not running | Restart server; check port |
CLAUDE.md not loaded |
Wrong filename or wrong directory | Check case, run from project root |
CompactionError |
Context too large to compact | /clear and start fresh |
Model not found |
Model ID string is wrong | Use exact ID: claude-sonnet-4-6 |
No — Claude Code requires an internet connection to call the Anthropic API. There is no local inference mode. If you need offline AI coding, look at locally-run models (Ollama + Continue, LM Studio) as an alternative, though they are significantly less capable than Claude Sonnet/Opus.
Because that command pattern is not in your allowedTools list. Add it to .claude/settings.json once and Claude will stop asking. See the permissions guide.
This is a CLAUDE.md issue. Add a style section:
# Code Style
- Language: TypeScript (strict mode)
- Formatter: Prettier (run automatically)
- Testing: Jest, never mock the database
- No inline comments unless the WHY is non-obvious
The VS Code extension and the CLI use separate credential stores. Run claude auth status in both the VS Code integrated terminal and a standalone terminal to compare. If different, re-authenticate in VS Code: open the Command Palette → "Claude Code: Sign in".
This happens when Claude gets confused in a long session — usually because it lost track of what's already been done. Interrupt with Ctrl+C, run /clear, and restart with a fresh, explicit prompt about the current state.
.claudeignore uses standard gitignore syntax but is evaluated independently of git. Double-check: (1) No trailing spaces; (2) Directory patterns end with / (e.g. node_modules/); (3) The file is at the project root; (4) Negation patterns (!important-file.ts) work only if a broader pattern already excluded it.
# Remove all Claude Code config (credentials, settings, memory)
rm -rf ~/.claude
# Reinstall
npm install -g @anthropic-ai/claude-code
claude auth login
~/.claude/ first if you want to preserve your settings.
The three biggest cost drivers: (1) Large context — each token in the prompt is charged, so reading big files repeatedly is expensive; use .claudeignore aggressively; (2) Opus instead of Sonnet — Opus is 5× more expensive; switch with --model claude-sonnet-4-6 for most tasks; (3) Prompt cache misses — if you start many short sessions, you pay full price every time; longer sessions with /compact amortize the cost better. See the pricing calculator for exact numbers.
claude --debug <your request> — verbose output usually shows exactly where it's failing.