Bug report template

A copy-paste bug report template in markdown for GitHub, Jira and Linear, with a filled example and the fields developers need to reproduce a bug.

bug report templatebug reportmarkdown

This is a bug report you can paste into GitHub, Jira, or Linear. It has the seven fields a developer needs to reproduce a failure: title, description, steps, expected, actual, environment, and evidence. The long version of why each field matters is how to write bug reports. This page is the block to copy.

The template

# Title

## Description

What broke, in one or two sentences.

## Steps to reproduce

1. …
2. …
3. …

## Expected behavior

## Actual behavior

## Environment

- Browser:
- URL:
- Account signed in:

## Evidence

- Screenshots:
- Console:
- Network:
- Link:

Filled example

This example is made up. It is here so the empty headings have a shape. It is not a report from a real app.

# Sign up goes to a 404

## Description

Clicking Create account on /signup navigates to /signup/new, which returns 404. The account is not created.

## Steps to reproduce

1. Open https://example.com/signup while signed out.
2. Enter a new email and a password the form accepts.
3. Click Create account.

## Expected behavior

The next screen is the account home, and the new email is visible.

## Actual behavior

The browser lands on https://example.com/signup/new. The page is a 404. No account exists for that email.

## Environment

- Browser: desktop Chrome
- URL: https://example.com/signup
- Account signed in: no

## Evidence

- Screenshots: the 404 page after the click
- Console: no error
- Network: GET /signup/new returned 404
- Link: n/a

GitHub, Jira, and Linear

All three can hold this report. The differences are where the file lives and how the editor treats markdown.

GitHub Issues renders the markdown. A repository can store the same body as .github/ISSUE_TEMPLATE/bug_report.md. GitHub reads the front matter below. labels is applied only when that label already exists in the repository. Issue forms (a YAML form in the same folder) are a different file. This is the markdown template.

---
name: Bug report
about: Report a defect with the steps to reproduce it
title: ""
labels: bug
assignees: ""
---

# Title

## Description

What broke, in one or two sentences.

## Steps to reproduce

1. …
2. …
3. …

## Expected behavior

## Actual behavior

## Environment

- Browser:
- URL:
- Account signed in:

## Evidence

- Screenshots:
- Console:
- Network:
- Link:

Linear issue descriptions are markdown, so the same headings paste as headings. Linear's own templates are created in Linear. There is no template file in the git repository that Linear reads.

Jira Cloud's default description field is a rich-text editor. Pasting this markdown keeps the words and the field labels. Headings can land as plain lines, and you format them in Jira's editor. Jira does not read .github/ISSUE_TEMPLATE. There is no Jira connection on this site that files the ticket for you.

What each field is for

Title. The failure in one line, specific enough to tell two bugs apart. "Sign up goes to a 404" can be searched. "It's broken" cannot.

Description. The outcome in a sentence or two, for the person skimming the list. Leave it out when the title already says the whole thing. Do not hide a second bug here.

Steps to reproduce. Numbered, in order, from a known starting point. Include the account state. "Go to the page and click around" is not a step.

Expected behavior. What the product should have done. Write the observable result, not a guess at the cause.

Actual behavior. What happened instead, including the URL, the status, or the text on the screen.

Environment. Browser, URL, and whether anyone was signed in. Add the build or the preview host when you have more than one. A bug that exists only in Safari needs the Safari version on this line. Opening that console is how to open the Safari console.

Evidence. A screenshot, the console text, the failed request's method, URL, and status, and a link to a recording or a run if you have one. Evidence taken while the failure happened beats a description written later.

The states a ticket moves through after this, from new to closed, are the software bug life cycle.

Filling the same fields from a Monito run

Monito does not create the ticket. Nothing here files an issue in Jira, Linear, or GitHub. You paste.

On a bug in the run report, Copy as issue puts markdown on the clipboard. The CLI prints the same body:

monito run view <id> --issue-markdown
monito run view <id> --issue-markdown --json

With --json the output is { "runId", "issues": [{ "bugReportId", "markdown" }] }. The process exits 1 if the run failed or errored. If the run has no bug reports, the text output is No bug reports for this run.

formatIssueMarkdown builds the body in this order:

  1. A title (#). If the bug has no title, the heading is Untitled bug.
  2. Description, only when the bug has one.
  3. Steps to reproduce.
  4. Expected behavior.
  5. Actual behavior.
  6. Environment: the environment name, and a link labeled "Tested URL".
  7. Evidence: a "View run report" link. A public report may also include a link to the first public screenshot. A private report does not add a screenshot URL.

Empty text becomes Not provided. URLs in the body lose userinfo, query, and fragment. A URL that cannot be kept is replaced with URL omitted. A value that looks like a masked credential (***, •••, [redacted], or [masked]) is replaced with credential omitted. Markdown punctuation in the field text is escaped, so a hyphen or a period in the title is written with a backslash. Do not expect a raw cookie or a query string to survive the copy.

That markdown is the evidence from Monito's run, not from a visitor session. You choose the tracker, you paste, and you set priority.

A check that could not verify the scenario ends Error. That is not an app bug to file as one. Read the cause first. What cannot verify means.

The run itself records screenshots, console messages, and network requests as method, URL, and status. A run with no login also records a video. A run that signs in keeps masked screenshots instead of a recording.

Run a check

Run your first test, then copy the report into the tracker you already use.

Related posts

Compare Monito with other tools
All Posts