Bug Report Template (Free, Copy-Paste) for Web, Mobile & API
Three free, copy-paste bug report templates — one each for web, mobile, and API — plus the one field reporters leave blank most often, and the GitHub YAML form that makes skipping it impossible.

This is the transactional version of a bug-report guide: you came for the template, so the templates are first, and you can copy any of them in one click. If you want the reasoning behind why these fields matter — what good looks like and why tickets bounce — read the companion piece, how to file a bug report developers actually want to fix. This page stays focused on the artifact.
One generic form does not fit web, mobile, and API bugs. A web bug needs the viewport and console; a mobile bug needs the device build and network type; an API bug needs the exact request and the full response. Forcing one shape onto all three is the quiet reason reports come back marked need more info.
The field people skip most — and why your template should fight it
Steps to reproduce is the single most-often-blank or low-quality field in a bug report. Researchers built automated grading (Chaparro et al., FSE 2019) precisely because reproduction steps are so frequently missing or incomplete, and missing steps are the dominant reason a developer cannot replicate the fault. Environment details rank second. Put steps first; autocapture the rest.
This is not opinion. In Assessing the Quality of the Steps to Reproduce in Bug Reports (ESEC/FSE 2019), Chaparro and colleagues built a tool called EULER to auto-grade reproduction-step quality — it correctly identified about 98% of the reproduction steps that were present, but it also flagged roughly 58% of the steps that were missing. The tool exists because incomplete steps are common enough to be the headline failure mode worth automating against.
The cost shows up downstream. A large-scale study of non-reproducible bugs (Rahman & Roy, 2022) analyzed 576 non-reproducible reports from Firefox and Eclipse, isolated 11 recurring causes, and ran a user study with 13 professional developers — who responded by either closing the bug or asking for more information. That back-and-forth is the exact tax a complete template removes.
Template 1 — Web bug report (copy-paste)
Use this for anything that happens in a browser: a broken layout, a failed form submit, a console error. The fields beyond steps and expected-vs-actual are the ones a capture tool should fill in automatically — keep them in the template anyway, so a manual reporter has a slot for each.
### Title
<!-- Specific + searchable. Bad: "checkout broken". Good: "Checkout fails with 'card_declined' on prepaid cards over $50" -->
### Steps to reproduce
1. Start from: <logged-out / fresh tab / specific URL>
2.
3.
4.
### Expected result
<!-- What should have happened -->
### Actual result
<!-- What actually happened, at the exact step it broke -->
### Environment
- Browser + version: e.g. Chrome 137
- OS: e.g. macOS 15.4
- Viewport / device: e.g. 1440x900 desktop
- App version / commit SHA:
- URL where it happened:
### Evidence
- Screenshot / video / session-replay link:
- Console errors (paste or attach):
- Failing network request (method, URL, status):
### Severity
<!-- blocker / major / minor / cosmetic — and why (e.g. "blocks production checkout") -->Template 2 — Mobile bug report (copy-paste)
Mobile adds variables a web template ignores: the exact device model, the OS build number (not just "iOS"), the network type, and — critically — whether the bug reproduces on Wi-Fi versus cellular. Race conditions and timeouts often only appear on one. Capture the build number, because "latest" is not a version.
### Title
<!-- Specific + searchable, include the screen: "Profile photo upload hangs at 99% on Android 14" -->
### Steps to reproduce
1. Start from: <cold app launch / specific screen / logged-in state>
2.
3.
4.
### Expected result
### Actual result
<!-- Include whether the app froze, crashed, or silently failed -->
### Environment
- Device model: e.g. Pixel 8 / iPhone 15 Pro
- OS + build: e.g. Android 14 (UP1A.231005) / iOS 18.4 (22E240)
- App version + build number: e.g. 3.2.1 (4471)
- Install source: TestFlight / Play Internal / Production
- Network: Wi-Fi / 5G / 4G / offline
- Reproduces on Wi-Fi? Y/N on cellular? Y/N
### Evidence
- Screen recording / screenshot:
- Crash log / stack trace (attach):
- Backend request ID or timestamp (for log correlation):
### Severity
<!-- blocker / major / minor / cosmetic — and the % of users / devices affected if known -->Template 3 — API bug report (copy-paste)
For an API bug, the report is the request and the response. A triager should be able to paste your curl command and watch the same failure. Give the exact method, endpoint, headers (redact secrets), and body, then the full response with its status code — and the environment or base URL, because staging and prod fail differently.
### Title
<!-- "POST /v1/charges returns 500 instead of 402 when amount exceeds balance" -->
### Endpoint & environment
- Method + path: e.g. POST /v1/charges
- Base URL / environment: e.g. https://api.staging.example.com
- Auth type: e.g. Bearer token (do NOT paste the token)
- API / client version:
### Request (redact secrets)
```
curl -X POST https://api.staging.example.com/v1/charges \
-H "Authorization: Bearer <REDACTED>" \
-H "Content-Type: application/json" \
-d '{ "amount": 9999, "currency": "usd" }'
```
### Expected response
<!-- Status code + body shape you expected, e.g. 402 with { error: "insufficient_funds" } -->
### Actual response
```
HTTP/1.1 500 Internal Server Error
{ "error": "internal_error", "request_id": "req_abc123" }
```
### Reproducibility
- Every time / intermittent (___ of 10 attempts)
- request_id or trace_id for log correlation:
### Severity
<!-- blocker / major / minor — and whether it affects production traffic -->Make the template un-skippable: a GitHub issue form
A Markdown template is a suggestion; a reporter can delete the headings and type one line. A GitHub issue form is enforced. Commit the YAML below to .github/ISSUE_TEMPLATE/bug_report.yml and GitHub renders a structured form with required textareas, a browser dropdown, and a type: bug label. With required: true on the steps field, a reporter physically cannot submit without it — which is exactly the field they'd otherwise skip.
name: Bug report
description: File a reproducible bug
title: "[Bug]: "
labels: ["bug"]
body:
- type: textarea
id: steps
attributes:
label: Steps to reproduce
description: Numbered, from a known starting state.
placeholder: |
1. Start from a logged-out tab at /pricing
2. Click "Start free trial"
3. ...
validations:
required: true
- type: textarea
id: expected-actual
attributes:
label: Expected vs. actual
placeholder: |
Expected: redirected to /onboarding
Actual: button spins forever
validations:
required: true
- type: dropdown
id: browser
attributes:
label: Browser
options:
- Chrome
- Firefox
- Safari
- Edge
- Other / N/A (mobile or API)
validations:
required: true
- type: textarea
id: evidence
attributes:
label: Evidence
description: Drag in a screenshot, video, or session-replay link.
validations:
required: falseGitHub's issue-form schema supports more field types than this — input, textarea (with code rendering), dropdown, checkboxes, file upload, and a type: bug designation — so you can grow the form to match the web, mobile, or API spine above. If your team already lives in GitHub Issues, this is the cheapest way to raise report quality across the board.
The capture-form shortcut: fields the reporter never types

Templates fix the fields a human must write. They do nothing for the fields a human forgets — and environment is the second-most-skipped field for a reason. A capture tool inverts the problem: instead of asking the reporter to remember their browser, OS, viewport, build SHA, console errors, and failing network calls, it records them automatically the moment the bug happens. The reporter is left with the one field that genuinely needs a human: a clear sentence and the steps.
With the BugMojo browser extension, a teammate highlights the broken element, types one line, and submits. Attached automatically: the last ~30 seconds of DOM mutations as an rrweb session replay, every console message in that window, every network request (status, payload, headers — PII redacted in the browser first), and the full environment block. The session replay means the steps to reproduce are no longer prose to be argued over — they are a recording you press play on.
The row no other template has: a report your AI agent can read
Every bug-report template you'll find — Atlassian's, GitHub's, and the rest — optimizes for a human triager. None of them ask the next question: can an AI coding agent read this bug and start fixing it? A structured template gets you halfway, because consistent field names let an agent parse steps, environment, and expected-vs-actual. The missing half is access — the agent still needs a way to fetch the evidence.
Be honest about the trade. A Markdown or YAML template is free, portable, and works in any tracker; that's a real advantage and BugMojo does not replace it. Where the templates stop is the machine handoff.
| Feature | Markdown / YAML template | BugMojo capture + MCP |
|---|---|---|
| Free + works in any tracker | ✓ | extension + sync |
| Enforces required fields | GitHub forms only | ✓ |
| Autocaptures environment | — | ✓ |
| Console + network attached | — | ✓ |
| Session replay of the bug | — | ✓ |
| Readable by an AI agent over MCP | — | ✓ |
| Nothing to install | ✓ | — |
BugMojo closes the access gap with an MCP server that exposes captured bugs — session replay, console, network, and environment — directly to agents like Claude Code or Cursor. The agent reads the same evidence a human triager would, instead of guessing from a one-line title. That's the row no competitor template page has, and it's the difference between a report a person re-traces by hand and one an agent can act on.
It doesn't work, plus an assumption the developer is telepathic, is still the most common useless report. A template's whole job is to make the fault reproducible by someone who wasn't there.After Simon Tatham, How to Report Bugs Effectively
Copy, paste, and make it the default
- Pick the right template. Web, mobile, or API — paste it into Linear, Jira, or GitHub and set it as the default issue template.
- Enforce the one field that gets skipped. If you're on GitHub, ship the
bug_report.ymlform withrequired: trueon steps to reproduce. - Autocapture the rest. Environment, console, and network are fields a tool should fill in — a reporter cannot forget what they never had to type.
- Make it agent-readable. If you want Claude Code or Cursor to act on bugs, the report has to be both structured and fetchable.
Install the free BugMojo extension: highlight the bug, type one sentence, and it attaches the replay, console, network, and environment your template would have left blank.
Install the extensionFrequently asked questions
Frequently asked questions
Sources
- Assessing the Quality of the Steps to Reproduce in Bug Reports (Chaparro et al., ESEC/FSE 2019) — ACM ESEC/FSE / arXiv (2019)
- Works for Me! Cannot Reproduce: A Large-Scale Empirical Study of Non-reproducible Bugs (Rahman & Roy) — Empirical Software Engineering (Springer) (2022)
- Free Bug Report Template (official Jira template fields) — Atlassian (2025)
- Configuring issue templates and YAML issue forms (bug_report) for your repository — GitHub Docs (2025)
- How to Report Bugs Effectively — Simon Tatham (PuTTY) (1999, maintained through 2025)
Get bug-tracking insights, weekly.
Engineering deep-dives, QA playbooks, and honest tool comparisons. No spam — unsubscribe in one click.

