All posts
4 min read

How to Write a Good Bug Report (for Humans and AI Tools)

'It's broken' can't be fixed. 'On /checkout, clicking Pay with an empty cart returns a 500' can. The five parts of a useful bug report, how to find reproduction steps, what evidence to attach, and a template you can paste into GitHub issues or your AI coding tool.

getting starteddebuggingAI agentsbeginner

The quality of a bug fix depends heavily on the quality of the bug report. That's true whether you're reporting to a developer, filing a GitHub issue, or asking Claude Code to fix something. AI tools, in particular, will happily "fix" a vague report by changing something plausible — and leave the real bug alone.

A good report takes two minutes more to write and saves an hour of back-and-forth.

The five parts

1. A specific title

Say what breaks and where.

  • ❌ "Checkout broken"
  • ✅ "Checkout returns 500 when the cart contains a discounted item"

2. Steps to reproduce

The exact sequence that makes the bug happen, numbered, starting from a known place:

  1. Log in as a normal user (not admin).
  2. Add "Blue Mug" to the cart.
  3. Apply the code SAVE10.
  4. Click Pay.

If someone follows your steps and sees the bug, it's half-fixed. If they can't, they're guessing.

3. Expected result

What should happen: "The payment page opens with the discounted total."

This matters more than it seems. Sometimes the app is doing exactly what it was built to do, and the "bug" is a misunderstanding about what it should do. Writing it down catches that.

4. Actual result

What happens instead, as precisely as possible: "An error page appears saying 'Something went wrong.' The browser console shows POST /api/checkout 500."

5. Environment and evidence

  • Where: production, staging, or your local copy? Which URL?
  • Browser and device, if it's a visual or front-end problem.
  • When it started, if you know — "after yesterday's deploy" is gold.
  • Error messages, copied as text, in full. (How to Read an Error Message.)
  • Screenshots or a short screen recording for visual problems.
  • Server log lines from around the time of the failure.
  • The failing network request — URL, status code, response body — from your browser's Network tab. (Browser Developer Tools for Beginners.)

Finding the reproduction steps

Often you don't know exactly what triggers the bug. Narrow it down:

  • Does it happen every time? If not, what's different when it does?
  • Does it happen for every user? Try another account, or a logged-out session.
  • Does it happen in an incognito window? If not, suspect cached data, cookies, or a browser extension.
  • Does it happen with different data? One product but not another points at something about that product.
  • Does it happen locally? If only in production, suspect configuration. (Why Does My App Work Locally but Not in Production?.)

Each answer removes a pile of possible causes.

One bug per report

"Checkout fails, also the logo is blurry, and emails are slow" becomes three half-fixed problems. Separate reports can be fixed, tested, and closed one at a time. This goes double for AI tools: one clear problem per request gets much better results. (How to Prompt AI Coding Tools.)

Don't include secrets

Before pasting logs or screenshots, check for passwords, API keys, tokens, and customers' personal data. Replace them with [REDACTED]. Public GitHub issues are public forever.

A template

**Summary:** Checkout returns 500 when the cart contains a discounted item

**Steps to reproduce**
1. Log in as a normal user
2. Add "Blue Mug" to the cart
3. Apply code SAVE10
4. Click Pay

**Expected:** Payment page opens with the discounted total
**Actual:** Error page. Console: `POST /api/checkout 500`

**Environment:** Production (yourapp.com), Chrome 140, macOS
**Started:** After the deploy on 23 September
**Evidence:**
Server log: `TypeError: Cannot read properties of null (reading 'percent')
  at applyDiscount (src/lib/cart.ts:48:31)`

Using it with an AI coding tool

Paste the same report into Claude Code, then add two instructions that make a big difference:

  1. "Reproduce the bug first, before changing anything." Ideally by writing a failing test. That proves the tool has found the real problem. (How to Write Tests With AI.)
  2. "Explain the cause before fixing it." If the explanation doesn't make sense, the fix probably won't either.

If a fix doesn't work after two or three tries, stop and rethink rather than asking again. (Stuck in an AI Fix Loop?.)


EasySpawn gives Claude Code the running app, its logs, and a real database in one persistent workspace — so it can reproduce a bug from your report instead of guessing at it. See how it works or join the waitlist.

Related: Debugging for Beginners · HTTP Status Codes Explained · Test Your App Before Launch

Keep reading