ProductHow it worksPricingBlogDocsLoginFind Your First Bug
A bug report split into the fields a triager fills from the specification and the fields a failing automated test can supply on its own
TestingBug Report TemplateBug Triage

Bug Report Template: The 7 Fields That Decide Triage

Tom Piaggio
Tom PiaggioCo-Founder at Autonoma

A bug report template names the seven fields a triager needs before acting on a defect: environment, steps to reproduce, expected result, actual result, severity, priority, and the evidence that proves what happened. The field almost every template gets wrong is expected result. It gets listed, but never anchored to where the expectation should come from: the specification, not the reporter's opinion.

If you're here because an interviewer asked you to name the fields, a junior engineer's first ticket just got kicked back marked "need info," or an auditor wants to see your defect template, you're in the right place. This isn't the QA lead's strategy document on where testing effort should go, and it isn't the argument about whether your AI-generated tests are testing anything real. It's the artifact a triager spends ten seconds on before deciding whether your defect gets picked up today or bounced back.

How a team decides what happens to a defect once it's triaged is a separate question, one the triage playbook already covers and the defect life cycle covers in more depth than a template article should attempt. What follows is narrower: the fields, filled in twice on the exact same bug, and the one field that decides whether either version survives triage at all.

The bug report template: 7 fields, each one justified

Every bug report opens with a one-line title, and that part isn't interesting: name the defect specifically enough that a triager doesn't need to open the ticket to route it. "Promo code fails to discount checkout total," not "checkout bug." The seven fields below are the ones that actually decide the outcome, and each earns its place for a different reason.

FieldWhy it's on the template
EnvironmentNarrows reproduction to what matters
Steps to reproduceFewest actions that trigger the fault reliably
Expected resultCites the specification, not a guess
Actual resultWhat the system verifiably did
SeverityHow badly the product is broken
PriorityHow soon it competes for engineering time
Attachments and evidenceProves the actual result happened

Severity and priority are the two fields most templates blur into one box. The distinction traces back to IEEE 1044-2009, the standard classification scheme for software anomalies: severity is a technical judgment, how badly the product is broken, and priority is a scheduling judgment, how soon it competes for engineering time against everything else in the backlog. A defect can be high severity and low priority (a crash in a feature nobody uses yet) or the reverse (a typo on the pricing page, live, during a launch). The cases where they pull apart are their own topic; here it's enough that the template asks for both, named separately, each justified on its own line rather than folded into one guess.

How to write a bug report: the same defect, twice

Here's one defect, filed twice, same day, same product. The bug: a valid promo code returns success from the API but never reduces the checkout total. The difference between the two reports isn't the defect. It's which fields got filled in as an afterthought and which got filled in as evidence.

Animated diagram showing observed failing-flow evidence and the specification combining into a triage-ready bug report.

The two animated inputs are complementary: a failing run establishes what happened, while the specification establishes what the product was expected to do.

The bad version. Title: "Promo code doesn't work." Environment: not specified. Steps to reproduce: "Go to checkout, put in a promo code, nothing happens." Expected result: "It should apply the discount." Actual result: "Nothing happens." Severity: not set. Priority: "ASAP."

The good version. Title: "Valid promo code SAVE10 does not reduce checkout total (REQ-CART-114)." Environment: Chrome 127 on macOS 14.5, staging, build 8f21a9c, at /cart/checkout. Steps to reproduce: add SKU-4471 ($40.00) to the cart, go to checkout, enter SAVE10 in the promo field, click Apply. Expected result: per REQ-CART-114 (Promotions spec, section 3.2), a valid unexpired code recalculates the total by its configured percentage before tax. SAVE10 is a 10% code, so $40.00 should become $36.00. Actual result: total stays at $40.00, no error shown, and the network tab shows POST /api/cart/promo returning 200 with { applied: true, discount: 0 }. Severity: major, checkout completes but a paid discount silently fails to apply. Priority: high, affects every use of the code this week and sits next to revenue.

Two bug report cards side by side for the same promo code defect: the bad version with a blank environment, an opinion-based expected result and no severity, the good version with the same fields filled in and the expected result citing REQ-CART-114
Same defect, same day. The bad version has an opinion where the good version has a citation.

Neither version invented information the other lacked. The good version just wrote down what was already true and verifiable: the build, the exact request and response, the spec section. Here's what actually flipped the triage outcome, field by field:

FieldBad versionGood version
Expected resultAn opinion, not citedCites REQ-CART-114 directly
EnvironmentLeft blankBrowser, build, and URL specified
Actual result"Nothing happens," unverifiableAPI payload proving discount is zero
Severity and priorityGuessed, marked "ASAP"Justified: revenue impact, no crash

A triager reading the bad version has three choices: guess, ask a clarifying question and lose a day, or close it "cannot reproduce." A triager reading the good version has one choice: assign it, because the report already did the work of proving a bug exists and pointing at where.

Expected result is a citation, not an opinion

This is the field a QA lead's process document skips and an interview question over-indexes on, which is exactly why it earns its own section instead of one line in a table.

In ISTQB terminology, "expected result" is not "what I wanted." It is a citation of the specification: a requirement ID, a spec line, a documented behavior, a prior release's screenshot, anything a triager can check independently of your judgment. When a report's expected result is "it should apply the discount," the only evidence behind it is that the reporter feels that way. That's not nothing, reporters are often right, but it's not verifiable on its own, and a triager cannot tell the difference between a correct hunch and a misunderstanding of the feature without doing the reporter's homework for them.

A bug report whose expected result is an opinion is a feature request with an angry tone.

That line is not a joke about tone. It's a triage mechanism. A feature request gets prioritized against a roadmap. A bug gets prioritized against risk. Filing the wrong one under the wrong label is how "the discount should apply" sits in a backlog for a sprint while the actual defect, an API silently returning a zero-value discount, keeps costing revenue. The citation is what tells the triager which queue the ticket belongs in, and it's the one thing a reporter's certainty cannot substitute for.

How Autonoma files a failure

Everything above assumes a human wrote the report from what they observed clicking through the app. That's still true for most defects. But a growing share of end-to-end coverage now runs as generated tests against a live build, and when one of those fails, the question changes: what can the failure record supply on its own, and what still has to come from a person?

A generated test that fails can carry the entire machine-observable half of a report, because it executed the steps itself rather than reconstructing them from memory. That means the exact sequence of actions, the browser and viewport the run used, a trace and video of the failure, the DOM state at the moment things went wrong, the network activity (including a response like a discount coming back as zero), the console output, and the exact commit the run was pointed at. Anyone who has filed a "cannot reproduce" closure knows how much of a human bug report is really an attempt to reconstruct exactly that, after the fact, from memory. A failing generated test doesn't reconstruct it. It was there.

What it cannot supply is the other half: whether the behavior it observed is wrong. Our platform's tests are generated from your codebase, so they know what a flow is supposed to do in the sense of what the code implements, but "supposed to do" in the specification sense, the actual requirement, still lives with the people who wrote it. That's not a gap we're trying to engineer away. Filing and tracking the resulting defect is a bug tracker's job, Jira, Linear, whatever your team runs, and Autonoma isn't trying to replace that, or a QA hire, or your unit and contract test layers. It produces the failure record. The test results dashboard is where that trace, video, and network capture actually live once a run completes, in the same place your team already checks after CI.

What the machine cannot fill in

Lay a bug report's fields next to that list of what a failing generated test can attach, and six of the seven sort cleanly onto the machine-suppliable side: environment, steps to reproduce, actual result, and the attachments that prove it. Severity and priority can often be inferred too, once the impact is visible in the trace. One field refuses to sort there. Expected result requires knowing what the answer should have been, and that requires the specification, not the execution.

Bug report fields split into two columns: steps reproduced, environment, trace, video, network activity and console output on the machine-suppliable side, and expected result alone on the human-only side because it requires the specification
Six fields sort onto the side a machine can fill. One doesn't, because it isn't observed, it's specified.

Most of the template existed because evidence was expensive to capture and had to be compressed into a paragraph typed from memory. Capturing it is no longer expensive.

What survives is the part that says what the answer should have been.

Working out why the API returned a zero-value discount, whether it's a stale pricing cache, a rounding bug, or a misconfigured promo rule, is its own exercise, root cause analysis, and it starts after this report is filed, not inside it. The report's job was never to explain the bug. It was to prove one exists and point precisely at where, and that job doesn't change no matter who or what wrote the steps.

Get this right consistently across a team, human-filed or machine-filed, and the fields stop being a compliance exercise. A defect escape rate built on reports with cited expected results and real evidence actually measures what testing caught. One built on reports like the bad version measures how often someone bothered to write a citation, which is a different number wearing the same name. Autonoma exists for the half of that record a machine can actually observe: what ran, where, and what happened. The half that says what should have happened stays exactly where it always was, with the person who knows the spec.

Frequently Asked Questions

A bug report template is a fixed set of fields a defect report must fill in before it goes to triage: environment, steps to reproduce, expected result, actual result, severity, priority, and supporting evidence. Filling in all seven fields makes a report actionable, but expected result is the one that decides the triage outcome, because it has to cite the specification, a requirement ID, a spec line, or documented behavior, rather than state the reporter's opinion of what should have happened.

A bug report should include a specific one-line title, the environment it occurred in (browser, OS, build, and URL), the exact steps to reproduce it, an expected result that cites something concrete like a requirement ID or spec line, the actual result observed, a severity and priority, and any attachment (screenshot, video, log, or network capture) that proves the actual result happened. The title and steps get a report routed; the expected result and evidence get it acted on.

Write the steps to reproduce as the smallest number of actions that trigger the fault every time, specify the exact environment and build rather than leaving it implied, and anchor the expected result to a source outside your own judgment, a spec line, a requirement ID, or documented behavior, instead of a preference. Then attach evidence, a screenshot, a video, or a network log, that proves the actual result rather than just describing it. A good bug report lets a triager act without asking a clarifying question first.

Actual result is what the system verifiably did: the output, error, or behavior you observed, ideally backed by evidence like a screenshot or log. Expected result is what the system should have done according to the specification, not according to personal preference. When expected result is an opinion rather than a citation, the report functions as a feature request rather than a bug, because there is no independent way to confirm the behavior is actually wrong.

Missing or vague environment details are the most common cause: a defect that only appears on a specific browser, build, or account state looks unreproducible if that context was never recorded. Steps that skip a required action, rely on data the reporter had but the tester doesn't, or describe the flow from memory instead of a live retrace also lead to a not-reproducible closure, even when the underlying bug is real.

Yes, and it should be set separately from priority. Severity measures technical impact, how badly the product is broken, while priority measures scheduling urgency, how soon it should be worked relative to everything else. A crash in a rarely used feature can be high severity and low priority; a visible typo during a launch can be the reverse. Filing both, justified rather than guessed, is what lets a triager sort a backlog instead of re-deriving impact from scratch on every ticket.

Autonoma can give a bug report a strong, reproducible starting point by running planned end-to-end checks in a live preview environment and identifying the failing flow. Use that run evidence alongside the environment and build context when you create the report. The expected-result citation still belongs to the specification and the person who can verify it, while a bug tracker such as Jira or Linear remains the system that records and routes the work.

Related articles

A two-by-two grid crossing severity against priority, with the two off-diagonal quadrants highlighted where a low-usage crash and a live pricing typo expose where teams actually disagree

What Decides Severity vs Priority? 2 Cases, 2 Owners

Severity vs priority: severity is how broken a bug is, priority is how soon a fix lands. The 2x2 with a real example per quadrant, and who owns each field.

A horizontal agent trajectory diagram showing a tool call passing a right-tool checkpoint but failing an argument-accuracy checkpoint

How to Test AI Agents That Take Actions (Tool Calls)

A runnable guide to testing tool-calling agents: right tool, right order, right arguments, mocked vs live calls, failure handling, and non-determinism.

A chatbot test pipeline moving from manual QA through scripted and semantic assertions into an automated CI gate that samples the model N times before allowing a merge

Chatbot Automation Testing: Why Assertions Fail

Chatbot automation testing that survives non-deterministic replies: the migration to a CI gate, n-run sampling, threshold gating, and real GitHub Actions YAML.

Sealed tenant data capsules being sorted into fully partitioned vault compartments, each isolated from the others, illustrating multi-tenant test data isolation

Multi-Tenant Test Data Isolation

What multi-tenant test data isolation means, why it matters for testing, and the four isolation patterns (schema, row-level, database, per-run) with tradeoffs.