Bug Report Template: The 8 Fields Developers Actually Need
By Sebastiaan Jansen · · 12 min read
A bug report template is a short, fixed set of fields that tells a developer how to see the bug, how bad it is, and when it counts as done. The useful version has eight fields: title, environment, steps, expected result, actual result, severity, evidence, and a done condition. Anything beyond that is optional context, and nobody should have to fill it in to file a bug.
Why a short bug report template beats a long form
The person who hits the bug and the person who fixes it are rarely in the same room. A form asks for the facts a developer looks for first, and it heads off the long writeup that still forgets to say how to reproduce the problem.
Teams without a template keep running into the same three failures. The ticket bounces back with "can't reproduce." Two people file the same bug under different titles. Severity depends on the reporter's mood, so a checkout failure ends up queued behind a typo. A product manager can still change severity, and a developer can still close a duplicate. The form makes those calls cheap.
The form and the tracker have to agree. Paste a careful template into a tool with no required fields and people will be skipping it by Friday. If you are choosing the tool, start with Bug Tracking Software: How to Choose One for a Small Dev Team.
The 8 fields this bug report template should include
Keep the labels stable so search, filters, and weekly triage all use the same words.
1. Title
One specific line someone can search for. Name the surface, the failure, and the condition if you know it.
Write "Checkout: tax shows $0 when the shipping country is Canada" instead of "Tax bug." That line is what people see in Slack, in standup, and in search six months later. If you don't know the trigger, say what failed and where, and leave the condition out.
A title that names three failures at once ("Tax, shipping, and email are all broken") is three tickets. Split them before filing, or the first fix will close the other two by accident.
2. Environment
Say where it happened so someone else can stand in the same place.
- App version, build number, or git SHA
- Browser and version, or mobile OS and device
- Account type, role, or tenant, if the bug is not global
- Production, staging, or a local branch
"Chrome 131, macOS 15, staging, admin role, build 2026.03.18" is an environment. "On my machine" is not. If you don't know the build, write "build: unknown." Writing "latest" sends the developer to the wrong release.
Name the data too, when the bug depends on it. "Northwind staging store, shipping country Canada, province Ontario" is part of the setup. A developer who reproduces against an empty US store will mark the ticket invalid and move on.
3. Steps to reproduce
Write numbered steps that start from a known screen, with one action per step. End on the step that makes the bug appear.
Three to seven steps is normal. A longer list is usually setup, and setup belongs in Environment. "Click Pay" is a step. "Try to complete the order" is a guess.
The usual miss is a step that hides two actions. "Set the shipping country to Canada and place the order" looks short, and it still leaves the next person guessing. Did the tax drop to zero when the country changed, or only after payment? Split it.
Wrong:
- Add the beanie, switch the address to Canada, and check out.
Right:
- Open the staging storefront as a logged-out shopper.
- Add the "Wool beanie" SKU to the cart.
- At checkout, set the shipping country to Canada and the province to Ontario.
- On the payment step, read the tax line.
The second list starts from a known screen, uses one action per line, and ends on the observation. If a step needs a record the developer does not have, name that record in Environment instead of burying it inside step 3.
4. Expected result
Describe the correct behavior in one or two sentences, tied to a rule the team already accepts: the spec, the help text, the previous release, or plain product sense.
"Tax should match the rate for the shipping country" is enough. If nobody can say what should have happened, you have a question rather than a bug.
Copy the rule, not a wish. "It should feel faster" is a preference. "The quote should use the shipping country, which is what the checkout help text says" is a bug. If two teammates disagree on the rule, write both readings in the ticket and let triage pick one before anyone starts a patch.
5. Actual result
Say what happened instead, in the same concrete terms. Include the exact error text, status code, or wrong value.
"Total stayed $48.00 and no error appeared" works. "It didn't work" doesn't. Write it in the same shape as the expected line so the gap is obvious at a glance.
A stack trace is not the actual result. Paste the trace under Evidence, and in Actual say what the shopper or the admin saw: the value on screen, the missing row, the toast that never came. The person who confirms the fix may never open the logs.
6. Severity
Pick one level from a scale the team agreed on before this bug existed. Four levels are enough for almost every team.
| Level | Meaning | Typical response |
|---|---|---|
| Blocker | A core flow is down, or data is wrong in a way you cannot undo | Fix or mitigate now |
| Major | An important path fails, and there is no reasonable workaround | This cycle |
| Minor | A path fails, and a workaround exists | Scheduled |
| Trivial | Cosmetic, copy, or a rare edge with little cost | Backlog |
Add the user impact in one clause: "Major. Checkout completes with the wrong tax for Canada." Skip a separate priority field unless someone else owns the commercial order of work. Severity measures harm, and priority sets the order.
A silent wrong charge stays Major even when a single merchant has seen it. A broken empty-state illustration with a working retry stays Minor. The reporter's frustration does not move the level. If you are unsure, file at the lower level and say why in the clause, so triage can raise it without rereading the thread.
7. Evidence
Attach a screenshot, a short recording, a log line, a Sentry event, a request ID, or a failing test. One piece of hard evidence is worth more than another page of description.
Crop the screenshot and paste the error verbatim. If the bug is intermittent, give the ratio: "Failed 2 of 5 attempts." Don't paste secrets, customer records, or session tokens.
A full-desktop screenshot hides the bug in a browser chrome, a Slack window, and a password manager. Crop to the control that is wrong, and leave the URL bar if the path matters. For a recording, start on the last known-good screen and stop one second after the failure. Ten minutes of clicking is not evidence anyone will watch.
8. Done condition
This tells a reviewer how to know the bug is fixed. Most templates leave it out, yet it's the field that stops a ticket from being reopened three times.
"On staging, a Canada shipping address produces a non-zero GST line, and the US tax test still passes." That is a done condition. "Fixed" is not. Someone who didn't write the patch should be able to run the check.
"Refactor the tax service" fails for the same reason. Name the screen, the input, and the value a reviewer should see. If the bug is a wrong stored value, say which record to open and which field to read. If it is visual, say the viewport and the state: "On a 390px-wide checkout, the tax line is visible without horizontal scroll." "Looks fine on mobile" is not a check.
A software bug report template you can paste
Copy this into the tracker as the bug description, or set the same labels as required fields. People on a deadline skip optional boxes.
Title:
[Area]: [what failed] when [condition]
Environment:
- App / build:
- Client (browser, OS, device):
- Account or role:
- Where (production, staging, local):
Steps:
1.
2.
3.
Expected:
Actual:
Severity:
[Blocker | Major | Minor | Trivial] — [one clause on user impact]
Evidence:
[screenshot, recording, log line, error ID, or "none yet"]
Done when:
[observable check a reviewer can run]
That block is the whole bug template. Sprint, points, and a customer quote can wait until after triage, where they won't get in the way of a reproduction.
GitHub documents the same idea as issue forms. Optional boxes stay empty, so make the fields above required.
Worked example: a wrong tax line
The numbers below are illustrative.
Title: Checkout: tax stays $0 when the shipping country is Canada
Environment: Web app build 2026.03.18, Chrome 131 on macOS 15, merchant admin, "Northwind" staging store. Production not checked.
Steps:
- Open the staging storefront as a logged-out shopper.
- Add the "Wool beanie" SKU to the cart.
- At checkout, set the shipping country to Canada and the province to Ontario.
- Leave the billing country as United States.
- On the payment step, read the tax line.
Expected: Tax shows Ontario GST/HST on the merchandise subtotal. The shipping country selects the rate, not the billing country.
Actual: Tax stays $0.00. The order can still be placed. No error toast appears. POST /checkout/quote returns "tax": 0.
Severity: Major. Shoppers can pay, and the order under-collects tax. Re-quoting in the admin is not acceptable for self-serve checkout.
Evidence: Screenshot of the payment step and the quote response, request ID quote_8f3a. Failed 3 of 3 tries.
Done when: The same five steps show a non-zero Ontario tax line, a US shipping address still shows US tax, and the quote test for a zero-tax state still passes.
The example doesn't guess that the rate table is missing Ontario, and it doesn't ask for a rewrite of quoting. It shows the request, the wrong value, and three checks a reviewer can run without the author in the room.
Bug report format for triage as well as filing
A bug report format has to hold up through filing, triage, and the fix. The eight fields cover filing. If triage ignores them, the tickets just sit there.
In triage, answer four questions and stop.
- Can we reproduce it from the steps and environment?
- Is it a duplicate?
- Is the severity honest?
- Is the done condition testable?
If you can't reproduce it, name the missing field when you send it back, because a bare "Needs info" gets ignored. Write the gap in one sentence the reporter can act on: "Steps start at 'click Pay' and never say which store or role. Add the environment and the screen you started from." A note like that gets a reply, while "Needs info" gets a paragraph or nothing.
If it's a duplicate, add the new evidence as a comment on the original, then close the new ticket. Don't merge five descriptions into one. Copy the new screenshot and the request ID onto the original before you close, or the only recording of the failure disappears with the duplicate.
Check severity twice, since reporters sit close to their own pain. A broken empty state is often Minor. A silent wrong charge is Major or Blocker even when only one customer has hit it. If the fix needs another browser, a regression test, or a backfill, widen the done condition during triage so the developer sees the finish line before starting.
Bugs need a stricter "ready" bar than ideas do. What an Issue Tracker Should Do in 2026 covers how that fits alongside other work.
What not to require
Every extra required field makes it less likely the important ones get filled.
- Suspected root cause. Fine when the reporter knows it, but a guess anchors the developer. Put hunches in a comment.
- Suggested fix. A one-line note is fine. A design proposal belongs in a different ticket.
- A second business-value score. Severity plus the impact clause already covers this.
- Assignee at filing time. Triage assigns. Auto-assigning the last editor creates a hidden queue.
- Passwords and full customer records. Link a shared test account from your password manager, and never store credentials in the body.
A HAR file, a redacted payload, or a feature-flag name can stay optional. Support can still file the eight fields from a call.
Where a bug comes from changes how you collect the fields, but the fields stay the same. A support rep should file with "build: unknown" rather than wait. An automated error still needs an expected result and a done condition before it counts as ready. A developer who hits the bug while coding should use the form too, because the next reader won't have the debugger open.
Chat is not a tracker. Slack Ticketing System: Turning Requests Into Tracked Work only helps when the message turns into these eight fields.
Make the tracker enforce it
Attach the template to the bug type. A wiki page nobody opens will not change Friday's tickets.
GitHub Issues can require a form, and Jira can require fields on a bug screen. Both break down when people file bugs as blank tasks. Jira Bug Tracking: Setup, Workflow and Common Mistakes and GitHub Issues as a Bug Tracker: Strengths and Gaps show where teams work around the setup.
Two habits undo the form anyway. Closing a duplicate without copying over the new screenshot throws away evidence. And "refactor the tax module" as a done condition describes a task, when it should describe a result.
Falrow can hold this as a bug ticket type with triage, so a report stays in triage until the fields are filled. Slack messages and Sentry errors can open those tickets. An error on its own counts as evidence, and the rest of the report still has to be written.
Start with the tracker you already have. Require title, steps, expected, actual, and severity on every bug. Require environment, evidence, and a done condition on Major and Blocker bugs. Rewrite five old bugs with the template, then adjust the help text based on what those five show you.
Pick the five from last month's reopened tickets, not from the ones that were easy to close. Reopened work is where a missing step or a vague done condition already cost a cycle. If all five were missing the same field, make that field required. If they were missing different fields, the help text is the problem, and a new required box will not fix it.
FAQ
What is a bug report template?
A bug report template is a fixed form that lets someone else reproduce a defect and confirm the fix. It asks for a title, environment, steps, expected result, actual result, severity, evidence, and a done condition. Extra fields wait until triage.
What should a bug report include?
Include where it happened, the steps, what you expected, what you saw, the impact, and proof. Add a done condition so the fixer and the reviewer share a finish line. Leave out guessed causes, credentials, and an essay on the business case.
How is a bug report different from a feature request?
A bug says an agreed behavior failed. A feature request asks for behavior the product does not promise yet. The expected-result field is where they split. If you can point to a spec, help text, or the previous release, file a bug. If you are arguing for new behavior, file a request, and don't use the bug severity scale to win that argument.
How detailed should the steps to reproduce be?
Detailed enough that a developer who has never seen the bug can follow them and watch it fail. Use numbered single actions, usually three to seven. Put role, data, and build in Environment. If the bug is intermittent, add the fail rate under Evidence.