Debugging for Claude Code. Commands that reproduce the bug and prove the mechanism before they touch a line, plus skills that make Claude write code that explains its own failures.
Frontend and backend, in the same toolkit — because half of all bugs live exactly on the seam between them, where each side has good evidence that it did the right thing.
Ask any AI to "fix this bug" and you get a patch. Sometimes the patch works. Often it's a
try/catch around the symptom, an ?. on the thing that was undefined, a setTimeout that
widens a race from daily to quarterly, or a dependency quietly removed from an effect's array.
The error goes away, nobody can say why, and the actual defect is still in there — now invisible.
The problem isn't the model. It's the prompt.
debugmaxxing encodes the discipline an experienced engineer applies:
- No fix without a reproduction and a mechanism. A repeatable trigger, and the exact line where the value stops matching intent. Otherwise it's labeled a hypothesis, with the experiment that would settle it.
- Reproduce before you theorize. Reading code first produces a list of things that could be wrong, none of which are the bug.
- Predict, then test. Every hypothesis comes with the observation that would kill it. Failed predictions get recorded under Ruled out, not quietly patched to survive.
- Never silence a symptom you can't explain. A null check is a fix when you know why the value was null, and a cover-up when you don't.
- Bisect over reading.
git bisect runfinds the culprit in log₂(n) steps and requires no understanding of the code at all. - If the fix works and you don't know why, it isn't fixed — and the report says so.
/plugin marketplace add kenjichristopherv-del/debugmaxxing
/plugin install debugmaxxing
Or, for local development:
/plugin marketplace add ~/Developer/debugmaxxing
/plugin install debugmaxxing
You do not need to read the rest of this page to use it.
/debugmaxxing:help my orders page shows £0 for every order
Describe what's wrong in your own words — no jargon required, no need to know which part of your app owns it. It walks you the whole way: works out what's happening, finds the cause, shows you the change before making it, and proves it's actually fixed. It tells you exactly what to type at each step rather than assuming you can read a stack trace.
It will also tell you plainly when it doesn't know, which is the point. Everything below is for when you want to drive it yourself.
You don't have to guess. One test decides it: reproduce the failure in the browser, then make the same request without the browser.
curl -i -sS 'http://localhost:3000/api/the-thing-that-is-wrong'| What you see | Which side | Go to |
|---|---|---|
| curl returns the same wrong result | Backend. The frontend is innocent — stop looking there | server, then db |
| curl looks correct, the browser is still wrong | Frontend. The right data arrived and something after that broke it | state, or ui if the data is right but it looks wrong |
| curl works, but the browser's request never arrives or is refused | The seam — CORS, preflight, cookies, auth headers, caching | network |
| curl can't reach it either | Below the app — process down, port, proxy, DNS | env, then server |
That single test collapses most investigations by half before you read a line of code. If you'd
rather just describe the symptom in plain English, /debugmaxxing:triage runs this reasoning for
you and hands you the one command to run next.
On server-rendered stacks — HTMX, Turbo, Hotwire, Jinja/ERB templates, Django, Rails, plain
SSR — the split lands somewhere different, and the labels below will mislead you if you take them
literally. Your "frontend" is HTML the server produced, so a wrong value on screen is almost
always a backend bug: start at server / db. The genuinely frontend-side failures are narrower
— how it looks (ui), and which element a fragment swaps into or why a control doesn't fire
(ui, then network if the fragment request itself is wrong).
Type /debug in Claude Code and they'll all filter into view.
The loop
| Command | Side | What it does |
|---|---|---|
/debugmaxxing:help |
either | Start here if you're new. The whole thing in plain English — symptom to verified fix, without ever handing you to another command |
/debugmaxxing:triage |
either | Don't know where to start — narrows it to one layer and one next command, in plain English |
/debugmaxxing:debug |
either | The full investigation: reproduce, localize by halving, prove the mechanism at file:line |
/debugmaxxing:repro |
either | Turns "it happens sometimes" into a one-command failing test — the artifact everything else depends on |
/debugmaxxing:bisect |
either | It used to work. Finds the commit, dependency, config, or data that changed |
/debugmaxxing:trace |
either | Instruments the code, runs it, reads the output, diffs a failing run against a passing one — then removes every probe |
/debugmaxxing:fix |
either | The only command that writes code. Fixes the cause at the right layer, verified against the repro |
/debugmaxxing:postmortem |
either | Timeline, root cause, why it wasn't caught, and action items that are structural rather than "be careful" |
The loop commands work on either side — they'll pull in whichever domain skill fits what they find.
By layer
| Command | Side | What it does |
|---|---|---|
/debugmaxxing:ui |
frontend | Layout, CSS, blank screens, elements that won't click. Computed styles and stacking contexts, not stylesheet archaeology |
/debugmaxxing:state |
frontend | Stale values, components that won't update, infinite effect loops, stale closures, hydration mismatches |
/debugmaxxing:network |
the seam | The client↔server boundary: CORS, preflight, cookies, caching, status codes, contract drift |
/debugmaxxing:server |
backend | Request lifecycle — routing, middleware order, parsing, auth, serialization, hangs |
/debugmaxxing:db |
backend | The query the ORM actually sent. Join fan-out, NULL semantics, transactions, locks, migrations |
/debugmaxxing:crash |
either | Reads a stack trace properly — the cause chain, the frame that matters, and why the value was wrong |
/debugmaxxing:async |
either | Races, deadlocks, double-submits, out-of-order events. Ends in a written interleaving |
/debugmaxxing:memory |
either | Leaks vs high watermark vs a limit that's too low — diagnosed by snapshot diff, not by reading |
/debugmaxxing:perf |
either | Measure, split the time, fix one thing, re-measure. Reports what wasn't the cause too |
/debugmaxxing:flaky |
either | Intermittent failures and flaky tests. Finds the hidden variable; refuses to call a retry annotation a fix |
/debugmaxxing:env |
either | "Works on my machine" — the config, version, build, container, or data difference |
/debugmaxxing:explain |
either | Explains the bug class against your code, so you catch it yourself next time |
Picked the wrong side? The command will tell you so and hand you back — that's a designed
outcome, not a failure. ui will say "this value is wrong before it reaches the template, go to
server" rather than trying to fix it in CSS.
Every command is read-only except fix (which writes patches), repro (which writes a failing
test), trace (which adds instrumentation and then removes it), and help (which patches, but
shows you the change and asks first).
Skills load automatically when Claude detects the relevant work — no command needed.
| Skill | Triggers on |
|---|---|
| debuggable-code | Writing error handling, catch blocks, logging, retries, or anything parsing external data. Supplies the pattern that makes the next failure explain itself |
| root-cause-method | Any debugging — the evidence discipline, the confidence ladder, and the finding format the commands share |
| frontend-debugging | Browser-side investigation: DevTools technique, hydration, stacking contexts, re-render analysis, and reading production telemetry when you can't reproduce it |
| backend-debugging | Server-side investigation: isolating the layer, query plans, thread dumps, replica lag, shutdown and deploy-window failures, container runtime |
debuggable-code is the quiet one that matters most. It doesn't wait for an incident; it makes
the error message name the value and the record the first time the error is written, which is
the difference between a two-minute investigation and a two-hour one.
/debugmaxxing:help <what's wrong> # start here if you want it walked end to end
/debugmaxxing:triage # start here if you're not sure what you have
/debugmaxxing:debug <the error> # start here if you are
/debugmaxxing:bisect # start here if it worked last week
help and triage overlap deliberately: triage is a signpost that points you at the right
command and expects you to drive from there, while help does the whole investigation and the
fix itself without handing you anywhere.
A good workflow: repro until it fails on demand, bisect if it's a regression, the layer
command for the mechanism, fix to patch the cause, and postmortem if it reached users.
Reproduce → prove → fix → prevent. The commands come as a loop. A reproduction is what makes a fix verifiable; a mechanism is what makes it explainable; the regression test is what keeps it dead. A bug you've watched fail on demand and then watched pass is a bug you can actually close.
PROMPTS.md — the debugging prompts as raw, copy-pasteable text. Use them in Cursor, Copilot, ChatGPT, or anywhere else; edit them for your stack; or read them to see exactly what the commands are asking for.
Start with Section 0, the preamble. It's the highest-leverage paragraph in the repo — paste it before any debugging prompt in any tool and the output quality changes immediately.
This is a rigorous investigator and a genuinely good teacher. It is not a replacement for your own instruments.
It reads code and, where you let it, runs commands — but it can't watch your production traffic, open your APM, or feel the thing that's wrong on a real device. Its conclusions are labeled by confidence for exactly that reason: Confirmed means it observed the mechanism, Likely means the story fits, Hypothesis means go look. Check the label before you act on the fix.
New prompts, better prompts, and corrections are all welcome — especially bugs where the
diagnosis went confidently wrong, since those become anti-guessing rules in root-cause-method.
Open an issue with the code, what was reported, and what the real cause turned out to be.
Apache 2.0 — see LICENSE.