If you use Claude Code professionally, the time you spend deciphering error messages starts to outweigh the time you spend writing code. What makes it worse is that similar-looking errors can come from completely different layers — auth, billing, model generation, tools, MCP, hooks — and the right fix depends entirely on identifying which layer actually failed. This handbook is the reference I wish I'd had two years ago: a symptom-indexed map of the Claude Code errors I've actually hit, each paired with the log to inspect, the root cause to verify, and the specific recovery path.
How to read this handbook
The handbook is organized into six chapters. When you hit an error, jump to the chapter that matches the symptom. Each entry follows the same four-part structure: symptom, where it's happening, how to inspect it, and how to recover.
- Authentication and permission errors
- Billing, card declines, and subscription problems
- Response stalls, incompletes, and timeouts
- Tool-call failures (Bash / Read / Edit / Write)
- MCP server and hook failures
- Environment- and config-driven compound errors
1. Authentication and permission errors
Authentication in Claude Code lives in two layers at once: the Anthropic account, and the local CLI credentials. When they drift — one expires, or the CLI holds a token for the wrong workspace — you get errors that look random but are actually deterministic.
Symptom: Invalid API key at startup
Your cached access token has expired or was silently overwritten by a different account. Check ~/.claude/credentials.json for the token's expiry. If it's stale, run claude logout && claude login. On macOS, also clear any stale Keychain entry: security delete-generic-password -s "Claude Code" before re-logging in.
Symptom: You do not have access to this organization
This appears right after being invited to a new organization or switching workspaces. The CLI caches an access token that hasn't re-scoped yet. Fix with claude config set workspace <workspace-id> or a full logout/login cycle.
Symptom: Partner Network returns 403 Forbidden
If your integration runs through Claude Partner Network, the partner-to-workspace binding can expire silently. Check the Partner Network dashboard, re-authorize on the partner side if needed. Partner Network tokens are distinct from your main Anthropic token — they don't refresh together.
Symptom: 2FA code never arrives
Confirm the email on file is still active. Corporate mail filters routinely quarantine no-reply@anthropic.com; ask IT to whitelist it. If you use an authenticator app and codes are rejected as invalid, your device clock has drifted — enable automatic time sync.
2. Billing, card declines, and subscription problems
Search traffic to my sites shows "card declined" and "payment failed" are by far the most common pain point. Almost all of these originate on the card-issuer side, not Anthropic's. Here's the triage order.
Symptom: Your card was declined, repeatedly
Check 3-D Secure first. Most non-US cards require it for international SaaS purchases, and Anthropic bills from the US. Enable the issuer's verification service (Visa Secure, Mastercard ID Check, J/Secure, etc.) and retry. This alone fixes most declines.
Second, make sure you haven't retried the same card three times in a minute. Rapid retries get flagged and blocked automatically. Wait ten minutes before the next attempt.
Third, some card brands aren't well supported by Anthropic's payment processor for international SaaS. If you've exhausted the above, switch to Visa / Mastercard / American Express. JCB and Diners tend to fail for this flow.
Symptom: Payment failed. Please contact Anthropic
This message indicates a risk flag from Stripe (Anthropic's processor), not the card itself. Common triggers: paying over a VPN, a mismatch between billing country and IP country, certain anonymizing proxies. Disable the VPN, open a private window (no cookies), and retry.
Symptom: Subscription renewal failed and my account is restricted
When automatic renewal fails, the account stays restricted for a brief window. Log into the web console, go to Billing → Update payment method, add a new card, and retry. Propagation can take 30–60 minutes — don't panic if Claude Code doesn't unlock instantly.
Symptom: I want invoice-based billing, not credit card
This is an enterprise-track option. You need to contact Anthropic Sales directly (sales@anthropic.com) with your usage profile, not change it in the web console. Mid-size teams on monthly contracts are eligible.
3. Response stalls, incompletes, and timeouts
I covered the fundamentals of incomplete responses in the free companion article; this chapter focuses on the compound cases that bite in production workflows.
Symptom: "Response incomplete" keeps happening during Extended Thinking
Extended Thinking burns through thinking tokens, which count separately from the reply but still extend the server-side processing window. Streaming connections die more often during that window. Fix in stages:
First, drop /think one level. If ultrathink stalls, try think hard; if that stalls, try plain think. If it passes, you were simply over budget.
Second, if the reply comes through but feels shallow, split the task. "Design and implement this" spends the budget twice; "design first, implement next" pays it per turn.
Third, if it keeps recurring, set thinkingBudget explicitly in ~/.claude/settings.json. Some environments default too high, and capping it stabilizes generation.
Symptom: Tool use timeout
Bash tool defaults aren't generous enough for monorepo-scale builds or large test suites. Either raise the tool timeout explicitly, or move long-running work to the background. A practical pattern: add to your CLAUDE.md, "For long-running commands, launch with nohup ... & and inspect progress via tail -n 50 <log>." Claude picks up on this pattern and uses it autonomously.
Symptom: I keep hitting the output token cap
If you bump the cap repeatedly, a better lever than raising max_tokens is changing the output format. Instead of asking Claude to re-output whole files, request a unified diff and apply it with the Edit tool. Output tokens drop by a factor of three or more, and you stop hitting the ceiling.
Symptom: The session is slow after hours of work
Above ~85% context, generation gets noticeably sluggish — not because Claude is "thinking" more, but because the context payload is large. Don't wait for auto-compaction; manually /compact, or dump your pending tasks to a note and restart via claude --resume. Personally, I compact around 70% for consistent performance.
4. Tool-call failures
Symptom: Bash tool throws command not found
The Bash tool runs as a non-interactive shell, so your .bashrc/.zshrc PATH edits don't load. Fix with a project-level .envrc via direnv, or add to CLAUDE.md: "Check existence with which <cmd> before invoking."
Symptom: Edit tool repeats old_string not found
Edit is the most brittle tool, and whitespace mismatch is the usual culprit — tabs vs spaces, different line endings, invisible Unicode. Two reliable fixes: (a) have Claude Read the file just before editing and paste the exact content as old_string; (b) keep old_string short and uniquely scoped (three to five lines around the target).
Symptom: Write refuses to overwrite an existing file
This is intentional. Write blocks overwrites of files you haven't Read, as a safeguard against accidental wipes. The proper workflow: Read first, Edit for modifications, reserve Write for genuinely new files.
Symptom: File upload fails
Web Claude's "Failed to upload" usually means size (>20 MB) or MIME mismatch. PDFs without OCR'd text, and encrypted PDFs, also fail silently. Re-save the PDF at lower resolution and try again. For Claude Code, skip Web upload entirely — keep the file local and Read it in.
5. MCP server and hook failures
Symptom: MCP server returns connection refused on startup
MCP servers launch as subprocesses, and their startup logs live at ~/.claude/logs/mcp-<server-name>.log. Connection refused almost always means the server binary isn't on PATH, isn't executable, or is missing a dependency.
Run claude mcp list to inspect state, then read the specific server's log. If the log says bind: address already in use, a prior process is stuck — pkill -f mcp-<name> and restart.
Symptom: My hook is registered but never fires
Check the JSON syntax first. A malformed ~/.claude/settings.json silently disables all hooks. Validate with jq . ~/.claude/settings.json.
Next, check matcher case. The matcher field is case-sensitive and exact-match. Bash works; bash does nothing.
Still silent? Add echo "hook fired" >> /tmp/hook.log to the hook command and watch the file. If it's firing but its logic misbehaves, inspect the exit code of the hook command.
Symptom: Hook fires, but Claude then freezes
If the hook script waits on stdin, it hangs the whole CLI. Hooks must complete within milliseconds. Any heavy work belongs in a nohup ... & background spawn, with the hook itself returning immediately.
6. Environment- and config-driven compound errors
These are the hardest to spot because the symptom surfaces far from the root cause.
Symptom: CLAUDE_CODE_USE_POWERSHELL_TOOL=1 doesn't enable the preview tool
Set location depends on shell: cmd.exe uses set VAR=1, PowerShell uses $env:VAR=1, WSL uses export VAR=1. A common trap: you set it in a shell profile that Claude Code's launch shell doesn't source. Confirm with claude --debug — the startup dump lists environment variables actually seen.
Symptom: CLAUDE.md seems to be ignored
Project-level CLAUDE.md must be at the repo root. Subdirectories aren't scanned. User-level goes at ~/.claude/CLAUDE.md. Both can coexist; project overrides user.
If it's in the right place and still ignored, check length. Very long CLAUDE.md (5000+ lines) may be truncated. Split: keep a short, concrete CLAUDE.md at the root, and link out to extended docs.
Symptom: claude --bare behaves unexpectedly
--bare launches with CLAUDE.md, MCP, and hooks all disabled. Use it as a bisection tool when something broke after a settings change — not as your default shell. If normal mode misbehaves but --bare is clean, the culprit is in one of those three layers.
Three rules that shorten every debugging loop
After walking through these categories, the pattern becomes clear: once you locate the layer, the fix is usually routine. To shorten the "find the layer" phase, three working rules that paid off repeatedly:
Read the log first, not the error. ~/.claude/logs/ has startup logs, MCP logs, and error logs. Ten seconds reading them beats ten minutes guessing from the visible message.
Pin down "where" before "what." The same error text can come from CLI startup, tool execution, or response generation. Tag your observation with a timestamp and the immediately preceding operation — the triage path shifts entirely based on that.
Shrink to a minimal repro. Turn "it feels broken" into "these three commands reproduce it every time." Claude Code's errors aren't probabilistic; given the same inputs, they behave the same way. Once reproducible, they're findable.
Keep this handbook bookmarked. The next time you hit something from one of these six chapters, skip the guesswork — jump straight to the matching entry and work the four-step recovery.