Debugging

Symptom, observation, hypothesis, experiment, evidence — and the anti-pattern of changing random things. Reproduction, minimal reproduction, binary search, logs as evidence.

Debugging Is Problem Solving
▶ lab

A bug is an unknown with a symptom attached. Symptom → observation → hypothesis → experiment → evidence → updated hypothesis is the same loop the domain uses for everything else, and it turns "Payment failed" into a sequence of questions each of which can be answered.

Q · The checkout page says "Payment failed" and you have no idea why. How do you make progress without knowing where the bug is?
Do Not Randomly Change Things
▶ lab

Error → change some code → restart → change something else is the most common debugging method and the worst. Instead ask what changed, what evidence exists, and which layer owns the symptom — three questions that cost less than one restart.

Q · You have been editing, restarting and re-trying for an hour and the error is still there. What should you have done instead, and how do you start doing it now?
Reproduce It First

A bug you cannot reproduce cannot be shown fixed. Before hypotheses, get the failure to happen on demand — the exact input, state and environment — and write down the recipe, because the recipe is the test the fix has to pass.

Q · A customer says checkout failed, you try it and it works. What do you do before forming any theory about the cause?
The Minimal Reproduction

Once the failure reproduces, remove everything that is not needed for it to keep failing — the UI, the real provider, the other tables, the framework — until what remains is small enough that the cause has nowhere to hide.

Q · The bug reproduces inside the whole store, with the UI, the API, the provider and the database all involved. How do you find out which of them actually matters?
Binary Search Over the System
▶ lab

Frontend or backend? Backend or database? Before commit X or after? Every debugging question that splits the candidate space in half is worth asking before any question that removes one candidate — and git bisect is the same move applied to history.

Q · The bug could be in any of five layers or any of forty commits. Which question do you ask first so that each answer removes the most candidates?
Logs Are Evidence, Not Thinking

A log line is an observation that was cheap to make in advance. It supports or kills a hypothesis; it does not generate one. "Add more logging" is only a plan when you can say which hypothesis the new line would distinguish.

Q · You have thousands of log lines and no idea what caused the failure. What is logging for, and how do you use it without drowning in it?
Reading the Error Message

An error message answers four questions if you let it: what failed, where, with what input, and which assumption broke. Searching the exact string first skips all four and hands your hypothesis to whoever wrote the top result.

Q · A stack trace is on the screen. What do you read before you search for it, and what does each part tell you?
Predict Before You Look

Before changing code or making an observation, say what you expect to see if your hypothesis is right and what you expect if it is wrong. The prediction is what turns a change into an experiment and stops "it looks fine" from meaning anything you like.

Q · You are about to make a change or check a log. What sentence should you write first, and what does writing it protect you from?