ChaosQA · Guides

How to write a bug report: a worked example on a web form

Updated November 7, 2026

A bug report has one reader, the person who will fix it, and one job: let that person see the bug without you in the room. The examples below are from a ticket checkout form, because forms are where most practice exercises put their bugs; the shape is the same for an API or a mobile screen. The reports are constructed for this page, not taken from anyone's tracker.

The four lines that do the work

Bug trackers offer many fields. Four of them carry the report; the rest can be short or empty.

LineWhat goes in itWhat it is for
StepsEvery action from a fresh page to the moment the bug shows, with the exact values typed. The last step is the action that triggers it. The developer repeats them. If a step is missing, they cannot reproduce the bug.
ExpectedWhat should have happened, and where that rule comes from: the requirements or the label next to the field. It marks the difference between a bug and a wish. "Expected: 10 tickets is the maximum, says the rule above the field" is harder to argue with than "should not allow that".
ActualWhat happened, in the words and numbers you saw. Copy the message; copy the total. Lets the developer match it to the code. "Wrong total" matches nothing; "₪104.9" matches a formatting call.
Where you saw itOn screen, in the confirmation, in the browser console, in the network request, in a second tab, on the server's response. Many bugs worth reporting are not on the screen. If you found one in the console, say so, or the developer will look at the screen, see nothing, and close the report.

Title, environment and severity are real fields, but they are derived from the four above. The title is the actual result in one line. The environment matters when the bug depends on it, which for a web form is rare; write the browser once at the top of the whole report. Severity is your estimate, and the guide on ordering findings covers how to set it.

Five reports, rewritten

Each pair below is a weak first version and the same report after a second pass. The form in the examples sells tickets at ₪119.90, charges a ₪5 service fee per order, gives students 20% off and the promo code SAVE10 10% off, with only the larger discount applied.

1. "The total is wrong"

Before: "The total is calculated wrong when I use a discount."

After: "Steps: 4 tickets, tick Student, promo SAVE10, Calculate total. Expected: ₪388.68 (479.60 minus 20% is 383.68, plus the ₪5 fee; the rule says only the larger discount applies). Actual: ₪350.31, which is both discounts applied one after the other (479.60 × 0.8 × 0.9 + 5). Seen on screen and in the order confirmation."

The second version names the input, shows the arithmetic for both numbers, and says which rule is broken. A developer can open the discount code and look for the place where the two discounts multiply. The first version sends them to try discounts at random.

2. "Doesn't accept my email"

Before: "The form doesn't accept my email address."

After: "Steps: 1 ticket, today's date, email [email protected], Buy. Expected: order placed, since the address is valid. Actual: the button goes grey for a second and nothing happens; no message, no confirmation. The request in the network tab returns 400 with {"error":"invalid email"}. The same order with [email protected] goes through, so the failure is capital letters."

The value is written out, so the reader does not have to ask which address. The silent failure is described as silent: no message is a separate problem from a wrong message. The last sentence reports the one experiment that narrows the cause without claiming to know the code: "the failure is capital letters" is something you saw, "the regex is case-sensitive" would be a guess.

3. "Date validation is broken"

Before: "Date validation is broken, I could enter old dates."

After: "Steps: event date 2026-03-14 (eight months ago), 1 ticket, valid email, Calculate total, then Buy. Expected: the field refuses a past date, as the rule 'today or later' says. Actual: the total is shown and the order is placed with that date in the confirmation. A date last year is refused with 'Please choose a date from today onwards', so the check looks at the year, not the full date."

"Old dates" could mean yesterday, last year or 1970, and these are different bugs with different fixes. The rewrite gives one date that fails and one that passes, which is what a developer will ask for first anyway.

4. "Clicked twice, got two orders"

Before: "If you click Buy twice you get two orders. Should be fixed, this is a common bug."

After: "Steps: 2 tickets, valid email and date, click Buy twice quickly (within about half a second). Expected: one order. Actual: two confirmations, orders #2041 and #2042, same email and date, total ₪244.80 charged twice. Clicking twice with a pause of two seconds gives one order and a 'you already ordered' message, so the guard exists but only takes effect after the first response arrives."

The first version was almost right; it lost the order numbers and the timing.

5. "Security issue in login"

Before: "Security issue: the login is not secure. High priority."

After: "Steps: open the sign-in form, enter [email protected] and the password, click Log in, then look at the page address. Actual: the address bar shows /api/login?email=anna%40example.com&password=Secret123, so the password is in the URL and will appear in the browser history and the server's access log. Expected: credentials sent in the request body (POST), nothing in the address."

A developer cannot reproduce "not secure". They can reproduce "the password is in the address bar". Here Actual comes before Expected; the report still has all four parts.

One bug per item

An item that says "the total is wrong and the date field accepts old dates" is two items. They have different causes, will be fixed by different people on different days, and one of them will be closed with the other still open. Split them. The opposite mistake is three items with one cause: a missing second decimal on the total, on the confirmation and in the email is one bug, formatting, reported once with the three places listed.

Before sending a list, read it once for pairs that are the same bug in different clothes. Merging them can shrink a list of twelve to nine, and the developer will thank you for the three.

What not to put in

Whether to list everything you tried that worked is a judgement call. Keep the one passing case that marks the boundary, as in examples 2 and 3; the other forty passing inputs usually belong in your notes, though a developer chasing an intermittent bug may ask for all of them.

The short form

In a chat or a practice report, where no one fills in a tracker form, one line per bug is enough if the line keeps the four parts:

One line per bug
4 tickets + Student + SAVE10 → ₪350.31 shown, expected ₪388.68 (only the larger discount should apply); on screen and in the confirmation.
Email [email protected] → Buy does nothing, no message; network tab shows 400 "invalid email"; lowercase address works.
Event date 2026-03-14 accepted and ordered; a date last year is refused, so the check is by year only.
Two quick clicks on Buy → orders #2041 and #2042, ₪244.80 charged twice; two seconds apart → one order.
Log in sends email and password in the URL (/api/login?email=…&password=…); should be in the request body.

Each line can be expanded into the long form on request, and each one can be checked by someone who was not there.

Before you submit

A report written by an AI agent can fail the first question in a particular way: the agent filled the form from a script, and the steps it writes are what the script did, not what a hand does. The guide on reviewing an agent's report goes through that case.

Try it on a live form. Each session of the TicketBox practice form plants 13 or 14 bugs. Write the report one line per bug, submit it, and the key shows which items a grader could match to a planted bug and which it could not. Check the unmatched items for a missing value or a missing place first.
Open the practice form

More guides: which bugs to report first · silent failures and stale screens · all guides