tech, developers, and the code underneath

issue 170· essay·

What a great bug report contains

Six fields. Most reports have two. The difference is measured in days of engineering time.

A bug report's job is to get someone to the reproduction as fast as possible. Everything else is decoration.

Most reports fail at this, and the cost is enormous — a round trip asking for information takes hours or days, during which the bug is not being fixed and the reporter is not being helped.

the six fields#

1. What you did. The exact steps. Not "I tried to log in" — the sequence, including things that seem irrelevant. The irrelevant thing is frequently the cause.

2. What you expected. This seems redundant and is not. A meaningful fraction of bug reports are misunderstandings, and stating the expectation surfaces that immediately. It also catches the case where the software is working as designed and the design is wrong, which is a different and often more important bug.

3. What actually happened. Specifically. The exact error text, copied, not paraphrased and not described. Screenshots for visual issues. The full stack trace, not the last line.

4. Environment. Version of the software, operating system, browser, region, account type, relevant feature flags. Half of all "cannot reproduce" outcomes are environment differences.

5. Frequency. Every time? Once? Intermittently? This changes the debugging approach completely — a deterministic bug is a logic error, an intermittent one is usually concurrency, caching, or state.

6. An identifier. Request ID, trace ID, session ID, timestamp with timezone, account ID. This is what lets an engineer find the actual event in the logs, and it converts "I have to reproduce this" into "I can look at exactly what happened."

That last one is the highest-leverage field and the one most often absent, because most products do not surface an identifier to the user.

If you build software: put a request ID on your error pages. It costs nothing and it is the difference between a bug report you can act on and one you cannot.

the title#

The title is read by dozens of people and determines whether the right person opens it.

Bad: "Login broken" Better: "Login fails with 500 for SSO users after password reset"

The pattern: what fails, for whom, under what condition.

what to leave out#

Your theory about the cause, unless you have evidence. A confident wrong theory sends the investigation in the wrong direction, and reports with a theory get debugged less carefully because the reader anchors on it.

If you do have a theory, put it at the bottom, labeled as speculation.

Emotional content. "This is completely broken and unacceptable" adds nothing and makes the reader defensive. The severity is communicated by the impact description, not by adjectives.

Multiple bugs in one report. One issue per report. Multi-bug reports get partially fixed and closed, and the remaining bugs are lost.

the minimal reproduction#

If you can produce one, it is worth ten times the rest of the report combined.

The technique: start with the failing case and remove things until it stops failing. The last thing you removed is involved.

This is work, and it is work that would otherwise be done by someone with less context than you. A minimal reproduction frequently reveals the cause to the reporter before they finish making it.

the template#

Put this in your issue template. Teams that do see a measurable improvement in report quality, because most people will fill in the fields you give them and will not invent them:

markdown
**What I did**
1.
2.
3.

**Expected**

**Actual**
(exact error text, full stack trace, screenshot)

**Environment**
- Version:
- OS / Browser:
- Account / Region:

**Frequency**
Always / Sometimes / Once

**Identifiers**
Request ID:
Timestamp (with timezone):

for the person receiving it#

The other half of this.

Reproduce before you theorize. The single most common debugging failure is building a mental model from the description and investigating that model instead of the actual behavior.

Ask for the missing field specifically. "Can you send the request ID from the error page?" gets an answer. "Can you provide more details?" does not.

Close the loop. Tell the reporter what it was. This costs a sentence and it is the reason people file good reports next time — a report that vanishes into a backlog teaches people not to bother.

the meta-point#

A bug report is a handoff of context between two people, one of whom has seen the failure and one of whom has to fix it.

Everything in a good report is in service of moving context across that gap. Everything that does not move context across the gap is noise.

get README in your inbox

One dispatch, no noise. Tech and developer news, plus the occasional long piece on the craft.

subscribe →