Article

What makes a bug reproducible

A reproducible bug names its preconditions, steps, and expected result so anyone can trigger it on demand and prove a fix worked.

bug reproductionqualitydebugging

A bug is reproducible when a second person, on a different machine, can follow written instructions and see the same wrong result. That is a higher bar than "I saw it happen." It is the bar that makes a defect fixable, testable, and provably closed.

Reproducibility is a property of the description, not of the bug. Two people can face the same defect while only one of them has a reproducible report.

What are the four required parts?

Every reproducible report contains four elements. Missing any one of them turns a fact into a guess.

Preconditions. The state that must exist before the steps begin: the account type, the plan, the stored data, the entry point, and anything unusual about the record involved. Most failed reproductions fail here, because the author knew the starting state so well they forgot to write it down.

Steps. The ordered actions, one per line, written as instructions to someone who has never used the feature. "Go to settings and update the profile" is a summary. "Select Account, select Edit profile, clear the Display name field, select Save" is a step list.

Expected result. What should happen. This is what separates a defect from a disagreement about intended behaviour.

Actual result. What happens instead, described observably. "Shows an error" is weak. "The page stays on the form and shows Something went wrong, and the old name is still displayed after reload" is strong.

How specific do the steps need to be?

Specific enough to remove every choice from the person following them. Each place where a reader must decide what you meant is a place the reproduction can silently diverge.

Compare these two versions of the same step:

Fill in the form and submit it.

Enter a display name of 80 characters, leave the time zone empty, then select Save.

The second version is reproducible because it names the data shape. Length, emptiness, unusual characters, and boundary values are the conditions that most often decide whether a defect appears.

Include the exact visible text of any error. Error text is searchable, it maps to a specific place in the source, and it distinguishes two failures that look identical to the user.

Which conditions get forgotten most often?

Some conditions are invisible to the person writing the report because they are constant in their own environment:

  • Identity. Signed in or out, which role, which permissions, how old the account is.
  • Data. Empty state, one record, or many records. A list that works with three items can fail with three thousand.
  • Sequence. Whether the visitor arrived directly, used browser back, refreshed mid-flow, or submitted twice.
  • Build. Which deployment was actually loaded. A visitor holding an old page in a tab is running code you no longer serve.
  • Timing. A slow connection changes ordering, and ordering changes behaviour.

A useful habit: after writing the steps, reread them as though you had a brand new account and no knowledge of the product. Every assumption you notice is a missing precondition.

Why does the exact build matter?

A report describes behaviour that existed at a moment in time. The source changes continuously. If you investigate today's code against yesterday's report, you may be reading a line that did not exist when the visitor hit the problem — or one that has already been changed.

This is why serious triage records which deployed commit the visitor was running. It converts "the profile page fails" into "the profile page fails in this specific version of this specific file", which is a claim you can verify by reading the source rather than by argument.

If your process cannot answer "which build was the visitor on", add that first. It removes a whole category of wasted investigation. The article on pinning a deployed commit covers how to make that mapping reliable.

What does a good report look like in practice?

A complete, reproducible report is usually short:

Preconditions: Signed in, Free plan, profile has no time zone set. Steps: 1. Open the profile page. 2. Enter a display name of 80 characters. 3. Select Save. Expected: The name saves and the page shows the new name. Actual: The page shows Something went wrong, the old name remains after reload, and the browser console shows a 500 response from POST /api/profile. Frequency: Every attempt, three of three.

That report can be handed to anyone. It states the starting state, the exact input, the observable failure, and the consistency. Nobody needs to ask a follow-up question before starting work.

Note what it does not contain: no password, no card details, no customer record, no guess about which function is at fault. Private values are never required to reproduce a defect, and a guessed cause tends to anchor the investigation on the wrong file.

How do you get this from real visitors?

Most visitors will not write a structured report, and asking them to is how you end up with no reports at all. The practical answer is to capture the observable context automatically at the moment of reporting, and to ask the visitor only for what a human can uniquely provide: what they tried, and what they expected.

IssueProbe takes that approach. A visitor describes the problem in a small widget, available in English, Portuguese, and Spanish, while the safe context — the page path, failed request metadata, bounded console errors, and metadata-only browser state — is collected alongside it. Screenshots are included only after a visible capture action, a preview, and explicit consent, and the visitor can remove one before sending. Each report can then start one read-only investigation against your repository at the deployed commit, and the result cites specific source locations or states plainly that the cause is unknown.

Next, read how to reproduce a bug from a vague user report for the questioning method, and what browser evidence helps for the context that removes follow-up questions.

Try the complete report review flow.

Start with one website and no payment card.

Start free