To write a bug report developers actually fix, give them one thing they can't argue with: an exact, reproducible path to the broken behavior. That means a specific title, the environment, numbered steps to reproduce, expected vs. actual results, a severity level, and evidence. Skip any of those and the report bounces back with "can't reproduce."

Disclosure: Clipy is our product. We keep competitor mentions factual and link their docs — tell us if anything reads as stale.

Most bug reports don't die because the bug is hard. They die because the report is thin. A developer reads "the export is broken," can't reproduce it, asks for more detail, and the reporter answers a day later with another vague line. A 30-minute fix becomes a three-day thread. This guide gives you a copy-paste template, a filled-in example, and a faster way to cover most of it: a short screen recording that documents itself.

Why good bug reports get fixed and bad ones don't

A developer can only fix what they can see happen. The whole job of a bug report is to move the bug from your screen to theirs with zero guessing in between. When a report is missing steps or environment details, the developer has two options: reproduce it by trial and error, or ask you. Both cost hours and both stall the fix.

The teams that ship fixes fast aren't more disciplined by nature — they use a consistent template so every report arrives complete. Atlassian's own bug report template makes the same point: a standard shape removes the back-and-forth. The fields below are that shape.

The anatomy of a bug report developers actually fix

Every field earns its place by answering a question the developer would otherwise have to ask you.

  • Title — What is broken and where, in one line. This is the summary in a triage list; it should read on its own.
  • Environment — App/URL, build or version, browser + OS or device, user role, and the time it happened. A bug that only appears on a specific build or role is invisible without this.
  • Steps to reproduce — Numbered, specific, verbatim. The single most important field. If a developer can't follow your steps and see the same defect, the report is dead on arrival.
  • Expected result — What should have happened. This tells the developer what "fixed" looks like.
  • Actual result — What happened instead. The contrast between expected and actual is where the bug lives.
  • Severity and priority — How broken it is, and how soon it needs attention. These are two different things (more below).
  • Evidence — A recording, a screenshot, and — for JavaScript or network bugs — a console error or HAR file.
  • Impact / scope — Who's affected, how often, and whether there's a workaround. This is what turns a ticket into a prioritized ticket.

The copy-paste bug report template

Paste this straight into your issue tracker or a Slack message. Fill the blanks and delete the guidance in parentheses.

Title: [Area] Short description of what's broken

Environment:
- App / URL:
- Build / version (commit if you have it):
- Browser + OS / Device:
- User role / account:
- Date + time (with timezone):

Severity: Blocker | Critical | Major | Minor | Trivial
Priority: P1 | P2 | P3 | P4

Steps to reproduce:
1.
2.
3.

Expected result:
(What should have happened.)

Actual result:
(What happened instead. Include any error message verbatim.)

Evidence:
- Recording:
- Console error / HAR (only if it's a JS or network bug):

Impact / scope:
(Who is affected, how often, and is there a workaround?)

A bug report example that gets fixed

The template above is abstract until you see it filled in. Here's the same shape for a real-feeling checkout bug — specific enough that a developer could start reproducing it in under a minute.

Title: [Checkout] "Place order" button does nothing on the payment step

Environment:
- URL: https://app.example.com/checkout/payment
- Build: web v4.18.2 (commit 9f3ac21)
- Browser + OS: Chrome 141 on macOS 15.5
- User role: Standard customer (test acct [email protected])
- Time: 2026-07-11 14:32 IST

Severity: Critical
Priority: P1

Steps to reproduce:
1. Log in as a standard customer and add any item to the cart.
2. Go to checkout and enter the test card 4242 4242 4242 4242, any
   future expiry, any CVC.
3. Click "Place order".

Expected result:
Order is submitted and the confirmation page loads.

Actual result:
Button shows a brief spinner, then returns to idle. No order is created,
no error toast, no page change. Reproduces every attempt.

Evidence:
- Recording: https://clipy.online/video/ab12cd34
- Console: Uncaught TypeError: cannot read 'id' of undefined (screenshot attached)

Impact / scope:
Blocks all web checkouts. Reproduced on 3 machines. No workaround.

Notice what makes this fixable: the exact card, the exact build, the exact error text, and a recording. A developer reading it doesn't have to interview you — they have a path and a symptom.

Severity vs. priority — don't merge them

These get conflated constantly, and the confusion misroutes tickets. Severity is how badly the software is broken. Priority is how soon the business needs it fixed. A cosmetic typo on your pricing page is low severity but can be high priority; a crash in an admin tool used twice a year is high severity but low priority.

Severity (how broken) Priority (how urgent)
Owned by The reporter / QA The team lead / PM
Blocker / P1 App unusable, data loss, no workaround Drop everything
Major / P2 Core feature broken, workaround exists This sprint
Minor / P3 Non-core issue, low impact Backlog
Trivial / P4 Cosmetic, typo, alignment Whenever

State your severity, and suggest a priority, but let the team set the final priority — you know how broken it is, they know what else is on fire.

Where text templates fall apart: the steps to reproduce

Here's the honest problem with the template. The reproduction steps are the most important field and the one people write worst. You know the bug so well that you skip the step your brain treats as obvious — the one filter you had set, the fact that you were on the second page, the specific order you clicked things. The developer follows your six steps exactly, doesn't see the bug, and closes it "cannot reproduce."

Writing perfect steps for a subtle interaction is genuinely hard. This is why "attach a screenshot" has been standard advice for a decade — but a still image shows one frozen moment, not the sequence that produced it. The fix for a sequence bug is a recording of the sequence.

The 30-second video method: let the recording write the report

Record the bug happening once and roughly 80% of the template fills itself in. The steps to reproduce are on screen. Expected vs. actual is what you say out loud while it happens. The environment — which app, which page, the browser chrome — is visible in frame. And the recording is the evidence field. You go from writing six careful steps to narrating one take.

Clipy is a free, no-watermark screen recorder built for exactly this. It runs in the browser with no install (there's also a Chrome extension, a native Mac app, and a Slack app), and you get a share link in under two seconds after you hit Stop. But the reason it replaces template fields — not just "attach a video" — is what's inside the link:

  • The video itself — the full sequence, so "steps to reproduce" is watchable instead of describable.
  • A transcript — everything you narrated ("this should save, but it just spins…") becomes searchable text next to the video. Your expected-vs-actual is captured as you speak it.
  • Key moments with extracted frames and click coordinates — Clipy pulls out the meaningful moments and, for each click, records where on the frame you clicked (x/y as fractions of the frame) with a still image of that moment. A developer scrubbing the report sees exactly which button you hit and in what order, without you writing it down.
  • A shareable, agent-readable link — every clipy.online/video/<id> link is also fetchable as a machine-readable .md document (append ?format=md or .json). That means the same link a teammate watches, an AI coding agent can read: it pulls the summary, key moments, click coordinates, and transcript straight into its context. If your team debugs with Claude Code, Cursor, or Codex, drop the link into the agent and it starts from the reproduction instead of a screenshot it can't parse.

On the native Mac app there's an extra layer: it records OS-level click semantics through the macOS Accessibility layer, so each click carries the element's role and visible label (for example, AXButton "Place order"), not just a pixel position. That turns "I clicked somewhere near the bottom" into "clicked the Place order button" — captured automatically.

If your workflow is agent-driven, we go deeper on handing recordings to coding agents in the agentic debugging workflow guide.

The honest limit: console and network still need a manual step

A screen recording captures what's visible. It does not read your browser's console or network tab — Clipy doesn't capture console logs, network requests, or response payloads, and we won't pretend it does. For a JavaScript error or a failing API call, the stack trace and the request/response live in your browser's developer tools, and you attach those yourself.

That's a 20-second manual step, and it's worth doing for any JS or network bug:

  • Console error: open your browser's developer tools (MDN's browser developer tools guide covers how to open the console in every browser), reproduce the bug, and screenshot the red error text — paste the exact text into the report, not a paraphrase.
  • Network failure: open the Network tab, reproduce, then right-click and "Save as HAR with content" to export a HAR file — a JSON log of every request, its status, and timing. Attach it (and scrub anything sensitive first; HAR files can contain cookies and tokens).

So the split is clean: the recording covers the reproduction, the timeline, and the visible symptom; the console screenshot or HAR covers the invisible technical cause. Together they leave a developer nothing to ask for.

A bug report checklist before you hit submit

Run this before you send any report:

  1. Could a developer who has never seen the feature reproduce it from your steps alone?
  2. Does the title say what's broken and where?
  3. Is the environment specific — build/version, browser + OS, user role?
  4. Are expected and actual results both stated, with any error message quoted verbatim?
  5. Did you set a severity?
  6. Is there a recording, and — for a JS/network bug — a console screenshot or HAR?
  7. Did you say who's affected and whether there's a workaround?

Seven yeses is a report that gets fixed. If you record the bug first with a free screen recorder, questions 1, 2, 4, and 6 answer themselves.

FAQ

What is the most important part of a bug report? The steps to reproduce. A developer can only fix a bug they can make happen on their own machine. Every other field supports that one — the environment tells them where to reproduce it, and expected vs. actual tells them what they're looking for. A recording of the exact sequence is the most reliable way to make steps reproducible.

What is the difference between severity and priority in a bug report? Severity is how badly the software is broken (from trivial to blocker); priority is how soon the business needs it fixed (P4 to P1). They move independently — a cosmetic typo can be low severity but high priority if it's on your pricing page. Report severity yourself; let the team set final priority.

Can a screen recording replace a written bug report? It replaces most of it — roughly 80%. A recording documents the reproduction steps, the expected-vs-actual behavior (via narration and transcript), and the evidence in one take. You still add a title, the exact build/version, a severity, and — for JavaScript or network bugs — a console screenshot or HAR file that a video can't capture.

How do I capture console logs or network requests for a bug? Open your browser's developer tools, reproduce the bug, and for a JS error screenshot the console; for a network failure use the Network tab's "Save as HAR with content" to export a HAR file. A screen recorder captures the visible symptom, but the console and network data has to be exported from devtools yourself.

How do I write a bug report an AI coding agent can use? Give the agent structured, reproducible input instead of a screenshot. A Clipy recording link is fetchable as a machine-readable .md document — transcript, key moments, and click coordinates included — so agents like Claude Code, Cursor, or Codex can read the reproduction directly. Add the exact error text and the environment, and the agent has what it needs to start a fix.