How to reduce 'cannot reproduce' bug tickets for good
"Cannot reproduce" is the most expensive close-reason in any bug tracker. The bug isn't fixed — it's filed away, still live in production, waiting to be re-reported by the next user. And the reason it gets closed is almost never that the bug is imaginary. It's that the report arrived missing the state that would make the failure happen again.
Reframe it and the fix becomes obvious: a "cannot reproduce" ticket is a missing-state ticket. A bug is deterministic when you hold four things constant. Drop any one of them in the report and the developer starts from a different place than the reporter did — and sees nothing wrong.
The four kinds of state that decide reproducibility
When a developer can't reproduce a bug, one of these four was missing from the report:
1. Environment
The exact build or release version, browser + version, OS, and the precise URL. "Latest" is not a version. A bug that was real on Tuesday's deploy is invisible on Thursday's — and a developer testing on main will never see it. The single most common silent gap is the build version: without it, you can't even tell whether the bug is already fixed.
2. Identity and data
Which account, which role, and which records were on screen. An enormous share of "cannot reproduce" bugs are really "only happens for admin users," "only on accounts with zero invoices," or "only when the cart has a discount applied." The developer signed in as a fresh test user with clean data and saw nothing. The state lived in the reporter's account, not the code path.
3. The action sequence
Not just the final click — the path that built up to it. Bugs that depend on order ("open the modal, close it, reopen it, then submit") or on stale client state are undetectable from the last step alone. The reporter rarely thinks the earlier steps matter, so they get dropped.
4. Runtime evidence
The console errors and failed network requests from the moment it broke. This is the highest-leverage item and the first one lost. A description written from memory ten minutes later has already dropped the 500 in the network tab and the stack trace in the console — the two things that would have pointed straight at the cause.
Why the state goes missing
It isn't carelessness. The reporter is a human who hit a wall mid-task and wants to keep working. By the time they open the tracker, switch tabs, and start typing, the build has been forgotten, the console has scrolled, and the failed request is gone. The further the report is written from the moment of failure — in time and in tooling — the more state has evaporated. The gap between "it broke" and "I filed it" is where reproducibility dies.
The fix: capture at the point of failure, automatically
You don't close this gap with a better bug-report template. Templates ask the reporter to remember and retype state they've already lost. You close it by capturing state at the instant of failure, from the page itself, without the reporter having to reconstruct anything.
Concretely, that means a report that auto-attaches:
- the build version and exact URL,
- the browser, OS, and viewport,
- a full-page screenshot of the actual broken state,
- and the console + network errors captured live, not described.
When those ride along automatically, the developer opens the ticket already standing where the reporter stood. "Cannot reproduce" stops being the close-reason because there's nothing left to guess at.
Make it measurable
Treat your "cannot reproduce" close-rate as a metric, not a fact of life. Count what fraction of bugs get closed that way each month. If the number isn't trending down, the problem is your intake losing state — not your code being mysteriously flaky. Teams that move capture to the point of failure watch that rate collapse, because the reports stop arriving with holes in them.
Where Klavity fits
This is exactly the gap Klavity Snap is built to close. Anyone — teammate, tester, or customer — can right-click on the page the moment something breaks and file a grounded report with the screenshot, console, network, build, and URL attached automatically. No template to fill, no state to reconstruct, no "can you try again and tell me the steps?" round-trip. The bug lands reproducible the first time. For deeper coverage, Klavity Sims sends AI personas through your product to surface these failures before a real user ever hits them.
Key takeaways
- 'Cannot reproduce' is a missing-state problem, not a flaky-bug problem — the report dropped the conditions that make the failure deterministic.
- Capture four kinds of state: environment (build, browser, OS, URL), identity/data (account, role, the records on screen), the action sequence, and runtime evidence (console + network).
- Evidence captured at the moment of failure beats any description written from memory — the decisive 500 or stack trace is gone within minutes.
- Make full-state capture the default path, not a discipline reporters have to remember. Tools beat checklists.
- Track your 'cannot reproduce' close-rate as a metric. If it isn't falling, your intake is losing state, not your code being flaky.
FAQ
Why do developers mark bugs 'cannot reproduce'?
Almost never because the bug is imaginary. It's because the report is missing the state that makes the bug deterministic — the exact build, the account and data, the steps that built up the broken state, and the console/network errors from the moment it failed. Without those, the developer is guessing at a different starting state than the reporter had.
Are 'cannot reproduce' bugs just flaky tests or race conditions?
Sometimes, but most are simpler than that: the reporter was on a different build, a specific account, a particular data set, or a sequence of actions that the developer didn't replicate. True non-determinism (timing, concurrency) is the minority. Capturing full state tells you which kind you actually have.
What's the single highest-leverage thing to attach?
The runtime evidence captured at the instant of failure — the console errors and failed network requests — plus the exact URL and build version. A description written from memory ten minutes later has already lost the 500 in the network tab and the stack trace in the console. That evidence is what turns 'cannot reproduce' into a one-line fix.
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