Claude Code diagnostics obey one rule: change one variable per step. The temptation to wipe the whole ~/.claude or reinstall the system at the first problem is strong but harmful - it destroys the evidence and gives no understanding of the cause. Before deleting anything you record the symptom, the version, the provider and a clean comparison. Diagnostics is narrowing, not a reset: each step should cut off one class of causes rather than zero out the whole environment at once.
A five-minute triage gives the first picture. In the shell you run claude --version, claude doctor and a trial claude --safe-mode; in an interactive session - /status, /doctor, /context, /mcp, /permissions, /sandbox. You record the exact error, the exit code, the time, the command, the current directory, the provider and model, the reproducibility - with redacted secrets before saving the log. This is not bureaucracy: without a recorded symptom any "fix" is a guess, and there will be nothing to compare "before" and "after" against.
The symptom almost always points to the first divider. It helps to gather this into a tree once: does not install - PATH and claude doctor; an auth loop and 401/403 - /status and conflicting credentials; 5xx and 429 - the error reference and the provider quota; a setting ignored - Setting sources and precedence; a hook not firing - claude --debug and the matcher case; MCP missing - location and approval; quality dropped sharply - a comparison of model, provider, context and version. You return to this map to go from symptom to the needed layer rather than guess.
| Symptom | First divider |
|---|---|
| Does not install / command not found | PATH, claude doctor, install troubleshooting |
| Auth loop / 401 / 403 | /status, conflicting credentials/provider vars |
| 5xx / 429 / timeout | Error reference, provider quota, retry |
| Setting ignored | /status Setting sources, JSON syntax, precedence |
| Hook not firing | claude --debug, matcher case, file location |
| MCP missing | .mcp.json location/type, approval, /mcp, health |
| Quality dropped sharply | Compare model/provider/context/style/version |
The clean-configuration ladder is the method of narrowing to the minimal culprit. First a normal run confirms the symptom. Then safe mode disables customizations, keeping the core, auth, model and permissions. Bare -p gives explicit minimal context for an automation symptom. A new temporary repository separates project config and data. A different network or provider (if allowed) separates transport. And only then are components returned one by one: settings, memory, hooks, MCP, plugin - until the symptom returns.
Flags help with this, not renaming files. --setting-sources and an explicit --settings let you bisect without touching user files; before any change you save copies or a diff and do not delete the OAuth state at random. It helps to see the triage commands side by side once. The point of the ladder is that each rung cuts off a whole layer of possible causes, and by the time the culprit is found you know exactly what causes it - not just "it started working after a reinstall".
Most problems are typical location mistakes, and they are worth knowing in advance. Settings put in ~/.claude.json instead of ~/.claude/settings.json; MCP in .claude/.mcp.json instead of the root .mcp.json; mcpServers wrongly written into settings.json; a hook moved into a standalone file, though only a plugin reads hooks.json; a matcher written as lowercase bash instead of the case-sensitive Bash; a skill created as name.md instead of name/SKILL.md; a project MCP not approved; a relative stdio command breaking at a different cwd. Each of these looks like a mysterious bug and is in fact a location mix-up.
Performance is treated just as pointedly. On context thrashing you ask to read specific ranges, do a /compact with focus, move large-file reading into a subagent or /clear; large build directories are added to gitignore and deny; safe mode finds a heavy plugin, MCP or hook. A separate caution with /heapdump: a heap snapshot contains the full conversation and credentials, so it is never attached publicly - for a report a documented diagnostics JSON after review is safer. And if the built-in ripgrep does not work, you install the system rg and set USE_BUILTIN_RIPGREP=0.
A bug report is also done by rules. A reproducible product bug is sent via /feedback or the official GitHub issues, with the version, OS, provider category, minimal steps, a sanitized debug excerpt and a safe-versus-bare comparison attached. Billing and account problems go to Anthropic support, not a public issue. The typical diagnostic failure is wiping ~/.claude before recording the symptom and losing both the evidence and the cause; the right move is to change one variable per step, walk the ladder and fix exactly one cause with a regression check.
# Five-minute triage
claude --version
claude doctor
claude --safe-mode
# in session: /status /doctor /context /mcp /permissions /sandbox
# ladder: normal -> safe-mode -> bare -p -> temp repo -> network -> components one by one