How to write a bug report developers can actually fix
Buganalyst
Ask any developer about the worst bug report they ever received and you will hear some variation of "it doesn't work." Ask about the best, and they will describe something almost clinical: steps, expectations, environment, evidence. The gap between those two reports is not talent or technical knowledge — it is structure. Anyone can write a bug report that gets fixed quickly, once they know what the person fixing it actually needs.
The three questions every report must answer
Strip away formatting conventions and every useful bug report answers three questions. What did you do? What did you expect to happen? What happened instead?
The third question is where most reports stop, and it is the least useful of the three in isolation. "The export failed" describes an outcome. "I selected March 2025, clicked Export as CSV, expected a download, and instead the button greyed out with no message" describes a fixable defect. The expectation matters because software frequently behaves as designed while still surprising users — and the fix for that is different from the fix for a crash.
When you write a report, state all three explicitly, even when they feel obvious. What is obvious to the person who just experienced the bug is invisible to the person reading about it later.
Reproduction steps: write them like a recipe
Developers fix bugs by reproducing them. A report with reliable reproduction steps is often fixed the same day; a report without them enters a purgatory politely labeled "cannot reproduce."
Good steps are numbered, start from a known state, and include the data involved. Compare "the search is broken" with a recipe: start logged in as a regular user, go to the projects page, type a term with a trailing space into search, press Enter, observe zero results even though matches exist. The second version hands the developer a failing test case in prose.
If you cannot reproduce the bug yourself, say so honestly and describe what you were doing when it happened. An intermittent bug honestly labeled intermittent, with its surrounding circumstances, is still valuable — it can be correlated with logs and other reports.
One report, one bug
Resist the urge to bundle. A report titled "several issues with the dashboard" that lists a rendering glitch, a slow query, and a typo will be triaged as the least urgent of the three, and the other two will be forgotten when it closes. Three small reports beat one omnibus report every time, because each can be prioritized, assigned, and closed independently.
Environment details: the silent half of every bug
A large class of bugs only exists in a specific context: one browser, one screen size, one locale, one account state. Reports written without environment details force a guessing game. Which browser and version, what device and viewport, which account or role, roughly what time it happened — these four facts turn "works on my machine" arguments into diagnosis.
This is also where tooling can quietly do the work for you. Reports submitted through an embedded widget carry the page URL, viewport, and user agent automatically, which means the reporter never has to know those details matter. If your reports come through email or chat instead, ask for the basics every time — or better, put the form where the bug happens.
Evidence beats adjectives
"The page looks terrible" invites debate. A screenshot ends it. For visual issues, attach an image; for sequence-dependent issues — things that go wrong after a particular order of clicks — a short screen recording is the single highest-value attachment possible. Ten seconds of video routinely replaces three rounds of clarifying questions.
Error messages deserve special care: copy the exact text rather than paraphrasing. Developers search codebases and logs for exact strings. "Some kind of permissions error" is unsearchable; the verbatim message is a bookmark into the code.
Tone: report the defect, not the developer
Bug reports are read by the people who will fix them. Reports written as accusations ("obviously nobody tested this") make triage slower, not faster, because they bury the signal in noise. The most effective reports are boring: factual, specific, and free of editorializing. Save your frustration for the retro; keep the report clinical.
A template you can steal
When in doubt, use this five-line skeleton. Title: a one-line symptom. Steps: numbered recipe from a known state. Expected: what should have happened. Actual: what happened, with exact error text. Environment: browser, device, account, time. A report in this shape, with a screenshot attached, is in the top few percent of everything a development team receives — and it gets treated accordingly.