Skip to content

Bug Reports: How to Write Ones Developers Act On

ILIA KARPENKO5 min read

A bug report is a record of one specific, reproducible failure: what someone did, what they expected, and what happened instead, written so a person who wasn't there can make it happen again on their own machine. A report that doesn't reproduce isn't a bug report. It's a rumor with a ticket number attached.

The cost of a bad report doesn't land on the person who filed it. It lands on the developer who reads "checkout is broken," can't reproduce it from that sentence alone, and now has to track down the reporter, ask three clarifying questions over chat, and wait for each answer before starting on the actual fix. A report missing steps to reproduce can turn a ten-minute fix into a half-day round trip, not because the bug was hard, but because the report made someone rediscover it from scratch.

What a report needs

FieldWhat goes wrong without it
Title"Checkout broken" doesn't triage and doesn't search. "Checkout fails with a 500 when a promo code is applied to a $0 order" does both, and someone scanning a backlog can tell at a glance whether it's a duplicate
EnvironmentBrowser, OS, app version, account role. Without it, "works on my machine" stops being a joke and becomes a real possibility nobody can rule out
Steps to reproduceA numbered, exact sequence from a known starting state. "Go to checkout and try to buy something" leaves out the one specific detail, the promo code, the $0 total, that actually triggers the failure
Expected resultWhat should have happened, stated plainly. Assuming the reader shares your mental model of "correct" is how a report gets marked "working as intended" and closed
Actual resultWhat happened instead, described as fact: the error message, the status code, the screen that appeared. Not "it's totally broken," which describes a feeling, not an outcome
EvidenceA screenshot, a screen recording, or a log line. It ends an argument about what actually appeared on screen instead of leaving it to memory

Steps to reproduce is the field that decides whether the rest of the report matters at all. A precise title and a clean expected/actual pair are still useless if nobody can get the system back into the state where the bug shows up.

Free and open sourceCasely writes these cases for youAttach a spec and one file of your team's existing test cases in Claude. Casely copies your columns, names the gaps it found in the spec, and exports a single Excel file your tracker imports in one pass.Read the install docs

Severity is not priority

Severity is how badly the bug breaks the system. Priority is how soon it needs a fix. They move independently, and conflating them is the single most common reason a real bug sits untouched for weeks.

A critical-severity bug in a feature three people use, gated behind a flag nobody enabled yet, can be low priority: it's genuinely broken, but fixing it today doesn't help anyone today. A minor-severity typo on the checkout page can be high priority, because it's visible to every paying customer and quietly damages trust in a screen where trust is the whole point. Filing both as "high" because they're both bugs erases the distinction a triage meeting actually needs: severity tells the developer how bad the code is, priority tells them what to work on next.

One bug per report

A report that bundles two problems, "checkout fails with a promo code, and also the confirmation email is missing the order total," can't be tracked cleanly. One half gets fixed, the other doesn't, and the report sits open or gets closed as fixed while a real, separate defect ships unaddressed. Split it into two reports the moment a second, unrelated failure shows up in the same investigation. Two clean reports triage, assign, and close independently. One compound report does none of those things well.

Where it fails

A perfect report still competes for someone's time. Steps to reproduce, evidence, and a clear severity don't force a fix to happen sooner if the bug doesn't touch revenue, doesn't affect enough people, or lands in a part of the product nobody's actively maintaining. The report format controls whether a bug can be understood and reproduced. It has no control over whether the team decides it's worth fixing this sprint.

A template doesn't force anyone to fill it out honestly. A report form with a "steps to reproduce" field still gets submitted with "N/A" in it by someone in a hurry. Structure lowers the chance of a bad report; it doesn't remove the person from the process.

Some bugs genuinely don't have a clean repro. A failure that shows up once every few hundred sessions, tied to a timing window or a specific device under specific load, may never yield a reliable numbered sequence. In that case the honest move is writing down what's actually known, frequency, conditions present when it did happen, anything correlated, rather than inventing steps that look precise but weren't actually verified to reproduce the bug.

What's worth automating

Capturing the mechanical parts of a report, browser, OS, app version, a screenshot at the moment of failure, console errors, is something bug-reporting tools already do without asking a human to type any of it by hand. What stays a judgment call is everything that requires understanding the product: writing an expected result that reflects what the system is actually supposed to do, telling severity apart from priority, and recognizing when two symptoms in front of you are actually one bug or two.

That's a different problem from deciding what a test case should check before anything breaks. Casely generates test cases from requirements, so a suite has a documented expected result before a test ever runs. A bug report is what someone writes after a case, generated or not, produced an actual result that didn't match. The two documents look similar on the page, expected versus actual, but one exists to define correct behavior in advance and the other exists to describe where reality diverged from it.

Open sourceThe skill lives on GitHubMIT licensed, no account, nothing to install on your machine. Star it if it saves you an afternoon.View the repository