What to do when you cannot reproduce a user bug
The five things that usually differ between your machine and theirs, and how to capture them before the report reaches you.
A ticket closed as "cannot reproduce" is rarely a ticket about a bug that does not exist. It is almost always a ticket about a difference between the reporter's environment and yours that nobody wrote down.
The five usual differences
Before assuming the report is wrong, check these. In practice one of them explains the large majority of unreproducible reports.
Browser and version. You develop in one browser. Your users are spread across several, on versions that lag by months. A feature you rely on may be behind a flag, shipped later, or implemented differently.
Viewport width. Not the device — the actual window. A user with a browser at 1100 pixels wide on a 27-inch monitor hits your tablet breakpoint, and no amount of testing on a real tablet reproduces it.
Time zone and locale. Date arithmetic that works in your time zone fails in one across the date line. Number and date parsing changes with locale. These bugs are invisible to a team that shares an office.
Session and account state. The bug happens for a user whose trial expired, who has one project instead of ten, or whose account was created before a migration. Your test account is none of those.
The route they took. They did not arrive at the broken page the way you do. They came from an email link, or clicked back, or submitted a form and edited it and submitted again.
Stop asking, start capturing
The standard response to this list is a better questionnaire: ask the reporter for their browser, their screen size, their time zone. That fails for the reason every long form fails — the person answering is guessing, and guessing badly.
The alternative is that the page collects those five facts at the moment the report is filed. Browser and version, operating system, window and screen size, pixel density, time zone and language are all readable from the browser in a few lines. The route is a list of the last clicks and page changes. Session state you already know, if your app passes the user id it already has.
When you still cannot reproduce it
Sometimes the context arrives and the bug still will not appear locally. Three moves are worth making before closing it.
- Reproduce the viewport exactly, not approximately. Set the window to the reported width rather than picking a device preset. Breakpoint bugs are precise.
- Look at the stack frame, not the description. If an exception was captured, the file and line are a fact even when the reproduction is not. Read what is at that line and ask what state would make it throw.
- Check whether it was ever true. Compare the report timestamp against your deploy log. A surprising share of unreproducible reports describe something that was real for forty minutes on a Tuesday.
Closing it honestly
If none of that lands, close it — but tell the person. "We could not reproduce this, here is what we tried, please tell us if it happens again" is a message that keeps a reporter engaged. Silence teaches them the report went nowhere, and that is how you stop hearing about the bugs you could have fixed.