Claude Code Debugging: Fix Common Issues and Errors in 2026
Last updated: April 15, 2026
Claude Code Debugging
Quick Answer
Most Claude Code issues fall into 8 buckets: binary not found, auth failures, slow sessions, stale file edits, missing test commands, MCP connection errors, cost spikes, and hook conflicts. The /doctor command diagnoses most of them. TLDR: run /doctor first, check the PATH, compact your context, or re-authenticate. Logs live at the config folder when you need a deeper look.
Summary of the 12 common issues and fixes
- Binary not found: add npm global bin to PATH
- Auth fails: rotate key or log out and back in
- Session feels slow: compact context or switch to Haiku
- Claude makes wrong assumptions: improve CLAUDE.md
- Edit fails on old_string: ask Claude to re-read
- Test command not running: check CLAUDE.md for command
- MCP server not connecting: use /mcp to inspect
- Cost spike: compact and check for runaway reads
- Hooks blocking valid ops: check hook exit codes
- Auto-accept danger: add PreToolUse hooks
- Out of context errors: aggressive compacting
- Subagent silent failure: watch terminal log
The /doctor command
The first diagnostic to run when something feels off. /doctor checks 5 things.
- Claude Code version vs latest available
- Node version compatibility
- Auth status (API key or OAuth token)
- CLAUDE.md paths being loaded
- Active hooks and settings.json config
The output tells you where things are set up correctly and where problems exist. For roughly 60 percent of issues, /doctor shows the fix directly.
Problem: claude binary not found
After npm install, claude --version says command not found.
Fix: the npm global bin directory is not on your PATH. Run npm config get prefix to find it, then add to your shell config.
On macOS with Homebrew Node, the path is usually /opt/homebrew/bin. On nvm setups, the path is ~/.nvm/versions/node/. Add the directory to .zshrc or .bashrc, reload the shell, and retry.
Problem: authentication fails
Claude responds with 401 or tells you the session is unauthorized.
Fix 1: rotate the API key. Old keys sometimes stop working after account changes. Generate a new one at the Anthropic console and update your env.
Fix 2: log out and back in. Run claude auth logout and then claude auth login. This clears any stale OAuth token.
Fix 3: check for conflicting env vars. If both ANTHROPIC_API_KEY and an OAuth session are set, the priority can be confusing. Pick one and clear the other.
Problem: session feels slow
Every turn takes 20 to 40 seconds and Claude seems sluggish.
3 likely causes.
Context is too large. Compact with /compact if you are above 40k tokens. Context over 100k tokens slows every turn because the full context ships to the API each time.
Model is too heavy. Opus is 5x slower than Sonnet. If the task does not need Opus reasoning, switch with /model sonnet or /model haiku.
Network latency. Check with a plain curl to the API. If curl is slow, the issue is your connection, not Claude.
Problem: Claude keeps making wrong assumptions
Claude proposes patterns you do not use, suggests libraries you already rejected, or picks the wrong file layout.
Fix: improve CLAUDE.md. Add a rule for each recurring correction. If you have told Claude the same thing twice in a session, it belongs in CLAUDE.md.
Also write more specific prompts. Instead of "refactor the auth module," try "refactor the auth module to use the Repository pattern, following the convention in src/users/repository.ts." Specific prompts produce specific answers.
Problem: Edit fails with old_string not found
Claude tries to apply an Edit and the tool responds that the old string is not in the file.
Cause: Claude memory of the file is stale. The file changed (either you edited it or a previous Edit already applied) and Claude is working from an outdated view.
Fix: ask Claude to re-read the file. A prompt like "re-read src/routes.ts and try the edit again" fixes this in most cases. After the re-read, the Edit call uses the current contents and succeeds.
A related trick: avoid editing files manually while Claude is in the middle of a sequence of edits on them. Let Claude finish or compact and restart.
Problem: test command not running
Claude tries to run the tests and gets command not found, or runs the wrong command.
Fix: check CLAUDE.md. The file should name the test command explicitly. If CLAUDE.md is missing the command or has an outdated one, Claude will guess, and guesses are often wrong on projects with multiple package managers or monorepo layouts.
Also verify the current working directory. Tests that work from the repo root may fail from a subdirectory if the test runner expects a specific cwd.
Problem: MCP server not connecting
An MCP server shows as not available or times out.
Diagnostic: run /mcp to see the status of every configured server. The command lists each server, its connection state, and any recent errors.
Common fixes. Restart the server: hit the restart option in the /mcp output. Check the config: open .claude/settings.json and verify the server command and args are correct. Check the server logs: each MCP server logs somewhere specific; check the docs for where.
A common trap: an MCP server that depends on an env var that is not set. Claude Code inherits env from the shell that spawned it. If you set env vars in a different shell, they are invisible.
Problem: cost spike unexpectedly high
/cost shows a session is much more expensive than expected.
3 common causes.
Long session without compacting. 50k to 100k tokens of context billed on every turn adds up fast.
Repeated file reads. Claude reads the same large file 5 or 6 times because it forgot it already read the file. Ask Claude to keep the file in mind, or break the session.
Runaway subagent dispatch. A subagent that recursively dispatches more subagents can burn through tokens silently. Limit depth and check the terminal log.
Problem: hooks blocking valid operations
Claude tries to run a command and a hook blocks it, but the command was legitimate.
Fix: check the hook exit codes. A non-zero exit blocks the call. A zero exit allows it. Log the hook input and output to find out which rule triggered.
Add exceptions by making the hook smarter. A hook that blocks rm -rf should only trigger on rm -rf / or rm -rf . A too-strict hook blocks legitimate cleanup and wastes time.
Problem: auto-accept running dangerous commands
Auto-accept runs a command you would have rejected.
Prevention first. PreToolUse hooks blocking destructive commands should be in place before auto-accept is enabled. See the auto-accept mode reference for the minimum hook set.
Recovery. git reset --hard to roll back committed changes. git stash to drop uncommitted changes. IDE local history to recover edits if git is not enough.
If you hit this more than once, auto-accept is premature. Turn it off until your hook set and test suite catch the danger.
Problem: out of context errors
A session fails with a context window overflow.
Fix: /compact drops the session into a summarized context and you continue. For very large sessions, /clear and restart from the summary that /compact produced.
Prevention: compact at 40k tokens, not at 180k when the wall hits. Setting a habit of regular compaction keeps the session in the healthy range.
Problem: subagent silent failure
A subagent returns nothing or returns a useless result.
Diagnostic: watch the terminal log while the subagent runs. The main session only shows the final summary, but the terminal shows every tool call. If the subagent failed early, the terminal log has the error.
Common cause: the subagent prompt was too vague. Subagents work best with tight briefs and specific file paths. A prompt like "refactor the auth code" gives too little direction; "refactor src/auth/session.ts to remove the callback pattern and use async/await" works.
Logging and tracing
Claude Code writes logs to ~/.claude/logs/. Each session has its own log with every tool call, argument, and result.
For a stuck session, open the log and scan for errors. For a cost investigation, open the log and count the file reads. For a hook debug, the log shows which hooks ran and with what result.
Logs rotate after 7 days by default. For longer retention, copy them elsewhere or adjust the retention in settings.
Getting support
3 channels when a problem resists the fixes above.
claude --bug opens the bug report flow. It collects the session state, the last 100 tool calls, and your settings, then prompts you for a description. Sends everything to Anthropic.
GitHub issues at the Claude Code repo. Search first for existing issues. If yours is new, include the claude --version output and a reproduction if possible.
The Anthropic community forum covers discussion and workarounds. Often someone hit the same issue last week and posted a fix.
For production-critical issues on a business account, Anthropic support has a ticket system with a same-day turnaround for paying customers.
Frequently asked questions
What does /doctor check?
Version, Node compatibility, auth status, CLAUDE.md paths, and active hooks. Run it first when something feels off. For roughly 60 percent of issues, the output shows the fix directly.
Why does claude say command not found?
The npm global bin directory is not on your PATH. Run `npm config get prefix` to find it and add the `/bin` subfolder to your shell config. Reload the shell and retry.
Why is my Claude Code session slow?
3 common causes: context over 100k tokens (run `/compact`), model too heavy for the task (switch to Sonnet or Haiku), or network latency between you and the Anthropic API.
Why does Edit keep failing with old_string not found?
Claude view of the file is stale. Another Edit already applied, or you edited manually. Ask Claude to re-read the file and retry. Avoid manual edits mid-sequence.
How do I debug MCP server issues?
Run `/mcp` to see every server and its state. Check `.claude/settings.json` for config errors. Verify env vars are set in the shell that launched Claude Code, since env does not cross shells.
Where are Claude Code logs stored?
At `~/.claude/logs/`, one file per session. Each log has every tool call, argument, and result. Logs rotate after 7 days by default. Copy them elsewhere if you need longer retention.