v1.4.0Triage that admits when there's nothing to find
Guides
  • Rhys Adams

The bug report template that actually gets bugs fixed

A good bug report answers four questions without a follow-up call: what did you do, what did you expect, what happened instead, and where's the evidence. Every field in the template below exists to answer one of those. Copy it as is, or take the GitHub and Jira variants further down.

#The template

## Title
One sentence describing the symptom, not the suspected cause.

## Environment
- Browser and version:
- OS and device:
- Deployed release or commit:
- Account / role (if relevant):

## Steps to reproduce
1. Start from a fresh session at <URL>
2.
3.

## Expected
What should have happened, in one sentence.

## Actual
What happened instead, in one sentence.

## Evidence
- Console errors (paste the full message and stack):
- Failed network request (method, path, status):
- Screenshot or recording:

## Regression?
Did this work before? If yes, roughly when did it break?

That's the whole thing. Seven sections, and most reports won't need all of them. Resist the urge to add more fields; every extra box lowers the odds anyone fills in the ones that matter.

#How to write a bug report worth reading

Write the title as the symptom: "Order total doesn't update when quantity changes", not "Cart bug" and not "Race condition in CartSummary". The first is searchable and specific. The last is a guess dressed as a diagnosis, and it sends whoever picks up the ticket down your theory instead of the evidence.

Number the repro steps from a fresh session. Half of all unreproducible bugs are unreproducible because the reporter started from state the reader doesn't have: logged in, cart pre-filled, feature flag on. Step 1 should be a URL a stranger can open.

Keep expected and actual to one sentence each. If you need a paragraph for either, the report is probably describing two bugs. File two.

The evidence section is the one that decides how fast the fix happens. A pasted console error with its stack turns an afternoon of guessing into a file and line. The failed request's method, path and status narrows it further. I'd trade every other field for these two.

And the regression question is cheap for the reporter and gold for the fixer. "Worked last Tuesday" plus a release number turns debugging into a diff between two versions.

#A filled-in example

## Title
Order total doesn't update when quantity changes on the cart page

## Environment
- Chrome 139, macOS
- Release v1.4.2
- Logged in, regular customer account

## Steps to reproduce
1. Start at https://shop.example.com/cart with one item in the cart
2. Change the quantity field from 1 to 3
3. Look at the order total

## Expected
Total updates to $36.00 (3 × $12.00).

## Actual
Total stays at $12.00 until a full page refresh.

## Evidence
- Console: TypeError: Cannot read properties of undefined (reading 'total')
    at recalcCart (cart-DZk1.js:2:18410)
- Network: POST /api/cart/recalc returned 500
- Screenshot attached

## Regression?
Worked on v1.4.1 last week.

Notice what the example doesn't contain: no severity matrix, no priority score, no speculation about the cause. Priority fields get argued about in comments; a 500 with a stack trace doesn't.

#GitHub and Jira variants

For GitHub, save this as .github/ISSUE_TEMPLATE/bug_report.yml and the form enforces the structure for you:

name: Bug report
description: Something broke
labels: [bug]
body:
  - type: input
    id: title-symptom
    attributes:
      label: Symptom
      placeholder: Order total doesn't update when quantity changes
    validations:
      required: true
  - type: textarea
    id: environment
    attributes:
      label: Environment
      placeholder: Browser, OS, release/commit, account state
    validations:
      required: true
  - type: textarea
    id: steps
    attributes:
      label: Steps to reproduce
      placeholder: "1. Start from a fresh session at <URL>"
    validations:
      required: true
  - type: textarea
    id: expected-actual
    attributes:
      label: Expected vs actual
    validations:
      required: true
  - type: textarea
    id: evidence
    attributes:
      label: Evidence
      placeholder: Console errors, failed requests, screenshot

In Jira, map the same sections onto the description template of your Bug issue type rather than custom fields. Custom fields feel rigorous but they're where evidence goes to die; a description template keeps the console output next to the steps that produced it.

#Where templates run out

A template can only ask. The fields that decide fix speed, meaning the console error, the failed request and the release, are exactly the ones reporters can't reliably transcribe, because that context lives on the page at the moment of the bug and is gone by the time they're filling in boxes. Templates raise the floor; they can't raise the ceiling.

That ceiling is why we built Rebase to capture those fields automatically at the moment of the click, and why the strongest reports contain a failing test instead of prose. Use the template for everything else. It's how bugs got fixed for decades before capture tools, and it still works.

One script tag. Every report ready to fix.

Free forever on one site. No card, no extension, no dashboard to learn.