"It Doesn't Work": Turning Vague Bug Reports Into Reproductions
A ticket came in once that said, in its entirety, “export is broken.” No screenshot, no browser, no account name. The engineer assigned to it spent forty minutes exporting things on staging, found nothing, and closed it as “cannot reproduce.” Two weeks later the same customer churned, and the exit survey said the export had been broken the whole time. It had — but only for CSV, only over 10,000 rows, and only in their timezone.
That ticket is the normal case, not the exception. If you want to reproduce a bug from a user report, you have to accept that the report will almost never contain what you need, and that this is not the user’s fault. Users describe outcomes (“it doesn’t work”), not mechanisms (“the POST to /export returns 422 when the date filter spans a DST boundary”). Translating one into the other is the actual job.
I spent two years sitting next to a support team, and the single biggest thing I learned is that the quality of a reproduction has almost nothing to do with how many questions you ask. It has to do with which ones.
Why it’s hard to reproduce a bug from a user report
Start with some empathy, because it changes how you write the follow-up email.
The user hit the bug while trying to do something else. They were mid-task, annoyed, and the report they filed is a side quest they never wanted. They don’t know what a console is. They don’t know that “it’s slow” and “it’s broken” are different investigations. And crucially, they’ve often already retried three times and mixed up what happened on which attempt.
So when the report says “it doesn’t work,” that’s not laziness. That’s a person accurately describing their experience at the level of detail available to them.
Your job is to extract the mechanism without making them feel interrogated — because a user who feels interrogated stops replying, and a report with no reply is a bug you’ll meet again in a churn email.
The five questions worth asking
After watching hundreds of these exchanges, I’d defend exactly five questions. Each one changes what you do next, which is the test a question has to pass.
-
“What did you expect to happen, and what happened instead?” This is the whole ballgame. Half of “bugs” are expectation mismatches — the feature worked, just not the way they assumed. You want to know which investigation you’re running before you run it.
-
“Does it happen every time, or did it happen once?” Deterministic and intermittent bugs are different species. A one-time failure points you at network conditions, race conditions, or a deploy window. An every-time failure points you at data or logic. This one question can cut your search space in half.
-
“What’s the email or username on the account where it happened?” Not “your account” — the account. Users report bugs they saw on a colleague’s screen, on a test account, on their second workspace. You need the exact identity so you can look at the exact data, because so many bugs that “only happen to me” turn out to be shaped by that specific account’s data.
-
“Roughly when did it happen?” Day and approximate hour is enough. This lets you line the report up against deploys, incidents, and — if you have them — logs and session recordings. Without a timestamp, you’re searching an ocean.
-
“Can you send a screenshot of what you see?” Not because the screenshot itself is usually decisive, but because it anchors everything else. A screenshot disambiguates which page, which state, which button. It catches the case where the user is on a completely different screen than the one you’ve been imagining for twenty minutes.
That’s it. Five. Notice what’s not on the list.
The ten questions that waste everyone’s time
These get asked constantly, and I’d argue most of them are theater — they make the asker feel rigorous while producing nothing actionable.
- “What browser are you using?” — Users say “Google.” They mean Chrome, or Edge, or a webview inside another app. Your instrumentation should capture the user agent automatically; if it doesn’t, the self-reported answer is unreliable anyway.
- “What version of the browser?” — Nobody knows this. Nobody should have to.
- “Have you tried clearing your cache?” — This isn’t a question, it’s a deflection. If clearing the cache fixes it, you have a cache-invalidation bug, and you just destroyed the evidence.
- “Have you tried a different browser?” — Same problem. You’re asking the user to run your bisection for you, and if it “works in Firefox,” you’ve learned little and burned goodwill.
- “Can you try incognito mode?” — Occasionally useful for extension interference, but as an opening question it reads as “we don’t believe you.”
- “What operating system?” — For a web app, this matters in maybe one bug in fifty. Capture it automatically or skip it.
- “What’s your screen resolution?” — If you suspect a layout bug, ask for the screenshot instead. It contains the answer plus everything else.
- “Can you record a video of it happening?” — You’re asking a non-technical person to install screen-recording software to help you fix your own product. Some will. Most won’t, and the ticket dies waiting.
- “Are you on VPN / corporate network / firewall?” — Legitimate in rare cases, but users often can’t answer accurately, and it comes across as pre-blaming their environment.
- “Can you open the developer console and tell me what it says?” — I’ve watched this exchange go four rounds. “Press F12.” “Nothing happened.” “Try Cmd-Option-J.” “I see a lot of yellow text?” It’s a coin flip whether you get the actual error, and the user has now spent fifteen minutes doing your job.
The pattern in all ten: they either ask the user for something a machine should have captured, or they ask the user to perform debugging steps on your behalf. Both are costs you’re shifting onto the person least equipped to pay them.
Asking without blaming
Tone matters more than engineers tend to think. Two phrasings of the same question:
“What steps did you take before the error?” — reads as what did you do wrong?
“I want to make sure I retrace your exact path — could you walk me through what you clicked, even the boring parts?” — reads as the bug is ours, help me find it.
The second version gets longer, better answers. It also gets the “boring parts,” which is where the reproduction usually lives — the filter they applied two screens earlier, the tab they left open overnight, the draft they restored.
One more habit worth stealing from good support people: always restate what you understood before asking anything. “So you clicked Export, the spinner showed for a while, and then the page went back to normal with no file — is that right?” Half the time the user corrects you, and the correction is the reproduction.
The endgame: stop asking
Here’s my actual opinion, and it’s the reason this article exists: every question you ask a user is a small failure of instrumentation.
The five good questions above are good because they cover the things a machine can’t know — expectations, identity, intent. Everything else — browser, OS, console errors, network failures, the exact sequence of clicks — can and should be captured automatically. Session replay with console and network capture turns “can you walk me through what you clicked” into “I watched what you clicked.” Error monitoring with user identity attached turns “roughly when did it happen” into a timestamped stack trace.
Teams that instrument this way still ask the five questions, but the questions become confirmations instead of expeditions. The ticket that says “export is broken” gets answered with “found it — CSV over 10k rows times out, fix going out Thursday” instead of a form letter asking about browsers.
And the bugs that survive even good instrumentation — the ones you genuinely cannot reproduce no matter what evidence you gather — deserve their own playbook, because at that point the problem usually isn’t missing information. It’s that you’re looking at the wrong layer.
But that’s the endgame. In the meantime: five questions, asked warmly, restated back. It’s slower than instrumentation and faster than everything else.
See the bug the way your user did
LogReplay captures session replays, console output, network requests, and errors in one timeline — so you stop guessing what happened before the ticket arrived.
Try LogReplay free