Debugging is controlled inquiry. Reproduce the failure, reduce irrelevant variables, form a falsifiable hypothesis, run one informative experiment, and verify the fix against both the failure and normal behavior.
Random edits produce activity but weak evidence.
Reproduce
Record the starting state:
- exact input;
- environment and relevant versions;
- current directory and command;
- expected behavior;
- actual behavior; and
- complete error text.
Run it again. If the failure is intermittent, record frequency and conditions rather than calling it reproducible.
Protect privacy. Replace real records with synthetic examples only after confirming that the replacement still reproduces the failure.
Reduce
Remove one irrelevant component at a time:
- fewer input rows;
- one function instead of the full application;
- local data instead of a service;
- minimal configuration; or
- one command instead of a script.
After every reduction, rerun the failure. If it disappears, the removed element may matter. Preserve the original safely and use Git or copies so reduction can be reversed.
Hypothesize
Write one explanation that predicts an observation:
Hypothesis: The parser rejects the file because the header contains a leading
space.
Prediction: Removing only that space will make the same input parse, while an
otherwise identical file retaining the space will fail.
“The parser is broken” is not specific enough. An AI suggestion is a hypothesis, not a diagnosis.
Test one variable
Design the smallest experiment that distinguishes the hypothesis from a plausible alternative. Change one factor, keep others stable, and add an experiment paragraph to the debugging record. State the changed factor, the predicted result if the hypothesis is true, and the observed result after the test runs. For example, write one paragraph for removing the leading space and another for keeping the space while changing the data row.
Do not fill in a Markdown experiment table. Unexpected results are useful; update the hypothesis rather than rewriting the prediction after observing the result.
Verify the fix
A fix must:
- make the original reduced case pass;
- make the original full case pass;
- preserve expected behavior;
- handle relevant boundary and invalid cases;
- avoid unrelated changes; and
- be documented when it changes assumptions or usage.
Inspect the diff and run existing tests. Add a regression test when the project supports it.
Write a debugging record
Do not fill in a multi-field Markdown form. Give the record a short title and answer these questions in short paragraphs:
- What failed, and what should have happened?
- Which environment and steps reproduce the failure?
- What is the smallest case that still fails, and what evidence did you remove while reducing it?
- What hypothesis did you test, what did you predict, and what single variable did you change?
- What result did you observe, what conclusion follows, and what remains uncertain?
- What fix did you make, and how did you verify the original, expected, boundary, and invalid cases afterward?
Use a title such as Leading space in parser input — debugging record. Add
details only when they help another person reproduce or verify the result.
Ask for help with evidence
Give a classmate, instructor, or AI tool the minimal case, complete error, hypothesis, and experiments already run. Follow course and data policy. Ask for another diagnostic step rather than an unexplained replacement solution.
Common mistakes
- Editing several variables simultaneously.
- Omitting full errors.
- Debugging stale generated output.
- Accepting the first plausible AI explanation.
- Removing validation to make the symptom disappear.
- Testing only the original failing example.
Do this now
Create a tiny safe program with a deliberate input-handling defect. Add one hypothesis paragraph and one experiment paragraph to the debugging record. Fix it only after the experiment produces evidence.
Log what you learned
The debugging record is the learning log. Add observations only after each test runs. Link the final fix, regression test, and commit when applicable. Next, design expected, boundary, and invalid tests before defects reach debugging.