Blog · Guides · 2026-07-28

How to Write Steps to Reproduce a Bug Anyone Can Follow

Klavity
TL;DRWrite steps to reproduce as a numbered list where each line is a single observable action, starting from a known state (the exact URL, account, and data) and ending with the expected vs. actual result. If a step needs a paragraph, it's really several steps — split it.

To write steps to reproduce a bug, list the exact actions a developer must take to see it, as a numbered sequence where each line is one observable action. Start from a known state — the precise URL, the account, and the data on screen — and end with the expected result versus what actually happened. The test of a good step list is simple: hand it to someone who has never seen the bug, and they hit it on the first try.

What are steps to reproduce?

Steps to reproduce (often shortened to "repro steps" or "STR") are the ordered actions that reliably trigger a bug in a running product. They are the single most important field in a bug report, because a developer cannot fix what they cannot see happen. Everything else in the report — severity, screenshots, logs — exists to support the moment when someone follows the steps and watches the bug appear.

Good repro steps are deterministic: the same actions produce the same failure every time. When they aren't — when a bug shows up "sometimes" — the steps are missing a variable. Something about the state, the data, the timing, or the environment is doing quiet work that the list doesn't name yet.

Why do reproduction steps fail?

Most repro steps fail for one of a few predictable reasons, and naming them makes them easy to avoid:

  • They start in the middle. "Click submit and it errors" assumes the reader is already on the right page, logged into the right account, with the right data entered. The reader isn't. Bugs live in state, and state has to be built from a known starting point.
  • They bundle several actions into one line. "Fill out the form and save" is at least four actions. If the bug is in the third one, a compound step hides exactly where things go wrong.
  • They describe intent, not actions. "Try to check out" tells the reader what you wanted, not what you did. "Click Place order" is reproducible; "try to check out" is a guess.
  • They omit the state you can't type. The specific account, the record with 400 line items, the feature flag that was on, the tab that had been open for an hour. These don't fit neatly in a numbered list, so they get dropped — and they're often the whole reason the bug exists.

That last category is the leading cause of the dreaded "cannot reproduce" resolution: the steps are technically correct, but the environment they ran in wasn't captured.

How do you write steps to reproduce a bug?

Use this sequence every time. It works for a two-line UI glitch and a ten-line data-corruption bug alike.

  1. State the starting point. Before step 1, write the exact URL, the account or role you're signed in as, and the relevant data on screen. "Logged in as a Free-tier user on /dashboard/settings with two saved projects" tells the reader where to stand.
  2. Write one action per line. Each numbered step should be a single thing a person does and can observe: click, type, scroll, wait, navigate. If a step contains the word "and," it's probably two steps.
  3. Use exact labels, not descriptions. Name the button, menu item, or field the way it appears in the UI — Place order, not "the checkout button." Quote the exact text you typed if the input matters.
  4. Mark the failure step. Point to the specific step where the bug appears, so the reader knows when to start watching closely rather than scanning the whole sequence.
  5. State expected vs. actual, separately. "Expected: the order confirms and the cart clears. Actual: the page spins for 30 seconds, then shows a blank screen." Two sentences, no ambiguity about what "broken" means.
  6. Trim what doesn't matter. Delete each step and re-run. If the bug still happens, that step was noise. What survives is the minimal path — the version that respects the reader's time.

Steps to reproduce: a bad example and a good one

Here is a report that will bounce back with questions:

"Saving a project doesn't work. It just errors out. Happens a lot."

Nothing here is reproducible. Which account? What project? What error? How often is "a lot"? Now the same bug, written to be followed:

  • Environment: Chrome 126, macOS 14, app v2.4.1, logged in as a Free-tier user.
  • Starting point: On /projects/new with the create-project form open.
  • 1. Type "Q3 launch" in the Project name field.
  • 2. Leave the Description field empty.
  • 3. Click Create project. ← bug appears here
  • Expected: The project is created and you land on its overview page.
  • Actual: A red toast reads "Something went wrong" and the project is not created. Reproduces every time when Description is empty.

The second version does the developer's investigation for them: it isolates the trigger (empty Description on the Free tier) and states the exact failure. That's often enough to jump straight to a fix.

How to capture the state your steps can't describe

Some of the most important context in a bug simply can't be written as a step. The console error, the failing network request, the browser version, the exact DOM state at the moment of failure — a person filing a bug rarely thinks to collect these, and typing them by hand is slow and error-prone. This is the gap that turns a correct step list into an unreproducible one.

The reliable fix is to capture that state at the moment the bug happens rather than reconstructing it later. In-app and right-click bug reporting tools do this automatically: Klavity Snap attaches a screenshot, the console log, network activity, and the environment to the report the instant a person flags a bug, so the evidence your written steps depend on ships with them instead of getting lost. Your numbered steps say what to do; the attached state proves where you were standing when it broke.

Write the steps for a human to follow, capture the state a machine can record, and "cannot reproduce" stops being the reflex answer. For the full report format that surrounds these steps, see our guide on writing a bug report developers will act on.

Key takeaways

  • Start every step list from a known state: exact URL, account, and data
  • Write one observable action per numbered line, no compound steps
  • End with expected result vs. actual result, stated separately
  • Capture state you can't type out — console, network, version — as attached evidence

FAQ

How many steps to reproduce should a bug report have?

As many as it takes to reach the bug from a known starting point, but no more. Trim every step that doesn't change the outcome by removing it and re-testing. A good report is often 3–8 numbered lines: most bugs don't need twenty steps, and the ones that do usually hide two or three that don't matter.

What's the difference between steps to reproduce and a minimal reproducible example?

Steps to reproduce describe the actions a person takes in the running product. A minimal reproducible example (MRE) is the smallest self-contained code and data that triggers the same bug in isolation. Steps to reproduce come first; you distill them into an MRE when the bug lives in code you can extract.

Do I need to include the environment in the steps?

Yes, but keep it separate from the numbered actions. Put the browser, OS, app version, account, and any feature flags in their own line above the steps. A step list that silently depends on a specific browser or a beta flag is why the same steps 'work on my machine.'

Catch bugs the moment a human sees them

Klavity: right-click bug reports, AI personas that review your product, and self-healing tests.

Get started free