How to write a bug report developers actually fix (2026 edition)

  • bug-reporting
  • qa
A man in a beanie points at one of dozens of colorful handwritten sticky notes arranged on a dark wall, while a smiling colleague with a notepad looks on.
Photo by Ketut Subiyanto on Pexels

A bug report developers actually fix contains five things: numbered steps to reproduce, what you expected versus what happened, the environment (browser, OS, URL, account), any console errors, and a screenshot or recording. The goal is simple — let the developer see the failure without a follow-up conversation. Everything below is a way of getting to that goal faster.

Why most bug reports fail

Ask a developer what happens after "the checkout is broken" lands in Slack, and you'll hear the same sequence: they open the page, it works fine for them, they ask which browser, wait an hour, ask for the account used, wait a day, and eventually get on a call to watch the reporter's screen. The bug takes ten minutes to fix and three days to understand.

Simon Tatham's classic essay How to Report Bugs Effectively put the principle well decades ago: the aim of a bug report is to let the programmer see the program failing in front of them. A report is good exactly to the degree that it substitutes for the developer standing behind your chair. Every missing detail becomes a round-trip, and every round-trip is a chance for the bug to be deprioritized, forgotten, or shipped.

A person holding a pen points at a whiteboard covered with colorful sticky notes during a team planning session.
Photo by Alena Darmel on Pexels

What every bug report needs

A specific title. "Checkout button does nothing on mobile Safari" beats "checkout broken." A developer triaging forty tickets decides in seconds which ones are actionable.

Numbered steps to reproduce. Start from a known state ("logged in as a customer with one item in the cart"), and list each action — including the ones that feel too obvious to mention. Bugs live in the steps people skip. If it only happens sometimes, say so, and say roughly how often.

Expected versus actual. Two lines. "Expected: order confirmation page. Actual: button spinner runs forever, no navigation." This is what turns an observation into a testable claim — the fix is done when actual matches expected.

Environment. Browser and version, OS, device, viewport size, the exact URL, and which account or role you were using. An enormous share of "works on my machine" is exactly that — a difference between machines that nobody wrote down.

Console errors. If the page misbehaved, the browser console usually says why. Copy the full error text, not a paraphrase — the stack trace and error code are the parts a developer searches the codebase for. Report what it says, not your theory of what it means; describing symptoms rather than guessing at causes keeps the investigation honest.

Network evidence. For anything involving loading, saving, or submitting, note the failing request: the URL, method, status code, and response body if you can see it. A 500 from /v1/orders and a CORS failure look identical to a user and completely different to the person fixing them.

A screenshot or recording. One picture resolves ambiguity that three paragraphs can't — especially for layout, styling, and "it flashed and disappeared" bugs. A short recording of the reproduction is even better.

Severity and impact, briefly. "Blocks all purchases on iOS" and "typo in footer" should not be triaged by luck. One line about who is affected and how badly is enough.

A copy-paste bug report template

## Title
[Component] Short, specific description of the failure

## Steps to reproduce
1. Go to <URL>
2. Log in as <role/account>
3. ...
4. ...

Reproducibility: always / intermittent (~X out of Y attempts)

## Expected result
What should have happened.

## Actual result
What happened instead. Paste exact error text where visible.

## Environment
- URL:
- Browser + version:
- OS / device:
- Viewport / screen size:
- Account / role:
- App version or commit (if known):

## Console output
```
Paste full console errors here (text, not a screenshot of text).
```

## Network evidence
- Failing request: METHOD /path — status code
- Response body / error message:

## Attachments
- Screenshot(s):
- Recording:

## Impact
Who is affected and how badly. Any workaround?

Delete sections that genuinely don't apply — an empty heading is noise — but be honest about the difference between "doesn't apply" and "couldn't be bothered."

The failure modes that stall fixes

  • The "it's broken" email. No steps, no URL, no environment. This report generates a conversation, not a fix.
  • Diagnosis instead of description. "The cache is stale" might be right, but if it's wrong, you've sent the developer down the wrong path. Report what you saw; offer your theory separately and label it as one.
  • Several bugs in one ticket. Each bug needs its own lifecycle. Bundles get half-fixed and closed, and the survivors are never seen again.
  • Screenshots of text. A screenshot of a stack trace can't be copied, searched, or grepped. Paste errors as text; save images for visual issues.
  • Missing account context. Bugs that only occur for certain roles, plans, or data shapes are unreproducible without knowing which user hit them.
  • Stale reports. A report filed a week after the fact, from memory, on a codebase that has deployed six times since. Capture at the moment of failure or accept degraded evidence.

Teams that handle a steady intake of reports usually solve this with structure rather than discipline — a shared template, required fields, and a capture tool at the point of failure. Our guide for QA teams covers how to make that stick across reporters who aren't QA professionals.

Writing bug reports when an AI agent does the fixing

A growing share of bug fixes in 2026 aren't implemented by the developer who read the ticket — they're implemented by an AI coding agent the developer pointed at it. That changes what a good report looks like, mostly by raising the stakes on things that were already good practice.

A human developer fills gaps with context and follow-up questions. An agent fills gaps with plausible assumptions — and a wrong assumption becomes a confident, wrong fix. What agents need is exactly the machine-readable evidence above: exact error strings and stack traces they can match against the codebase, request/response pairs with status codes, precise URLs that map to routes and components, and structured fields rather than prose. "The console showed TypeError: Cannot read properties of undefined (reading 'items') at CartSummary.tsx:42" is something an agent can act on directly. "There was some error about items" is something it will guess about.

The practical rule: write reports as if the first reader is a machine and the second reader is a human, because increasingly that's the actual order. Text over screenshots-of-text, exact strings over paraphrases, one bug per report.

Why auto-captured context beats human transcription

Everything in the template above is knowable at the moment the bug happens — and almost all of it is tedious and error-prone for a human to transcribe. Reporters copy errors partially, truncate stack traces, misremember their browser version, and skip network evidence entirely because DevTools is intimidating. None of this is a diligence problem; it's a tooling problem.

Capture tools solve it by recording the technical half of the report automatically: screenshot, console output, network requests, environment metadata — all attached the moment the reporter clicks a button. The human contributes the parts only a human knows: what they were trying to do, and what they expected. If you're evaluating tools in this space, we've written honest comparisons against Jam and Marker.io, including where each one is a better fit.

This is what BugPort does: the browser extension and embeddable widget capture the screenshot, console logs, network requests, and full environment in one report, at the moment of failure, and file it to your tracker — so the reporter types two sentences and the developer (or agent) still gets the whole picture. See how it works on the bug reporting page.

FAQ

What is the most important part of a bug report?

Steps to reproduce. A developer who can make the bug happen on demand can almost always fix it; a developer who can't is reduced to guessing. Expected-versus-actual is a close second, because it defines what "fixed" means.

How long should a bug report be?

As short as possible while remaining reproducible. A tight report — numbered steps, two lines of expected/actual, environment, pasted error, one screenshot — usually fits on one screen. Length is not thoroughness; a rambling narrative with no exact error text is long and useless.

Should I include console and network logs even if I don't understand them?

Yes — especially then. The exact error text is the most searchable, actionable artifact in the report, and you don't need to interpret it, just include it. If opening DevTools isn't realistic for your reporters, use a capture tool that attaches console and network logs automatically at the moment the bug is filed.

Do bug reports need to change for AI coding agents?

The fundamentals are identical — agents just punish vagueness harder than humans do. Exact error strings, precise URLs, status codes, and structured fields give an agent real evidence to match against the codebase; paraphrased errors and screenshots of text force it to guess. Auto-captured reports are effectively agent-ready by default.

← All posts