Back to blog
Engineering21 min read

Free Bug Report Prompt Generator (Repro Steps Included)

A bug report generator that interrogates you before writing: repro steps, expected vs actual, environment, honest severity. 19 prompts by reporter type, plus a full interrogate-then-assemble example.

NH
Nafiul Hasan
Founder, Prompt Architects

TL;DR: A bug report generator that writes a polished report from one vague sentence produces one nobody can act on: the reporter usually doesn't know what the fixer needs, and the model can't ask on its own. The prompts below interrogate first and assemble second, covering repro steps, environment, honest severity, and reporter type, from developers to outside vendors.

Why does a "write a bug report" prompt produce a report nobody can act on?

Paste one line into ChatGPT: "write a bug report about the login button not working." What comes back reads like a bug report. It has headers, bold labels, maybe a severity tag. It is also close to useless, because the model had one sentence to work with and filled every gap with something plausible instead of admitting it didn't know.

This is the actual failure mode behind most AI-assisted bug reports, and it isn't really the model's fault. A bug report fails when it's missing information the person fixing it needs, and the reporter, not the model, is usually the one who doesn't know what that is. A first-time reporter doesn't know that "expected vs actual" has to be two separate sentences, that "intermittent" needs a rough frequency attached, or that "recently" means anything that changed in the last deploy, the last dependency bump, or the last config edit. The model doesn't know either, and unlike the reporter, it will not stop to ask unless you tell it to.

So the tool that actually helps isn't a bug report generator in the write-it-from-nothing sense. It's an interviewer that refuses to draft anything until it has answers, and only then assembles them into a report shaped for whoever reads it next. That reordering, questions before output, is the whole idea behind this page.

What does a fixable bug report actually need?

Eight things separate a bug report someone can act on from one that gets bounced back marked "needs more info." Skip any one and you've shifted investigation time from the reporter, who has the context, to the fixer, who doesn't.

ComponentWhat goes wrong if you skip it
PreconditionsFixer can't tell which state the bug depends on, so they test the wrong path first
Exact repro stepsNumbered, one action per step; "it happens sometimes" is not a step
Expected vs actualTwo separate sentences; without both, "broken" means nothing specific
Environment and versionOS, browser or app version, build number; a bug that already shipped a fix looks open otherwise
Frequency and first occurrence"Always," "about half the time," or "since Tuesday" tells the fixer whether to look at a recent change
What changed recentlyA deploy, a dependency bump, a config edit; often the fastest route to a root cause
Severity, honestly framedNot every bug blocks every user; inflated severity trains people to discount your reports
Attachments worth includingA screenshot of the actual error, not a paraphrase of it; a log or console capture beats a description of one

None of these need jargon. They need specificity, and specificity is exactly what an interrogation prompt extracts and a one-shot prompt cannot, because a one-shot prompt has to guess instead of ask.

The interrogate-then-assemble prompt, shown end to end

Here is the full sequence on one real example: a CSV export that downloads a file with headers but no rows, once a date filter has been applied first.

Prompt 1: the universal interrogation

I need to file a bug report, but don't write one yet.

Before you write anything, ask me these questions. Do not attempt to
draft the report until I've answered all of them. If I don't know an
answer, I'll say NOT PROVIDED, and you must carry that forward as
NOT PROVIDED rather than guessing.

1. What were you doing right before this happened? (preconditions)
2. What are the exact steps, in order, starting from a clean state?
3. What did you expect to happen?
4. What actually happened instead?
5. What app/OS/browser version, and on what device?
6. How often does this happen, and when did you first see it?
7. Did anything change recently: a deploy, an update, a settings change?
8. On a scale that isn't "critical" by default, how bad is this really:
   does it block the core task, or is there a workaround?

Here's the problem in my own words: <describe the bug in one or two sentences>

Here's what a reporter actually typed back, unedited:

  1. I'd just finished filtering the table to last quarter's orders.
  2. Open Reports, filter Date range to Q2, click Export CSV, open the downloaded file.
  3. A CSV with the filtered rows.
  4. A CSV with headers only, zero data rows.
  5. Chrome 131 on macOS 15, app version 4.2.1.
  6. Every time I filter first, then export. Exporting with no filter works fine. First saw it this Monday.
  7. NOT PROVIDED, I don't know what shipped, that's for you to check.
  8. Blocks my weekly report, but I can filter in a spreadsheet after an unfiltered export as a workaround.

Prompt 2: the assembly, using only those answers

Using only the eight numbered answers above, assemble a bug report in
this exact format. Do not add any detail I did not give you. If
something is missing, write NOT PROVIDED. If you infer anything from
context, prefix it with INFERRED and explain the inference in one
clause.

TITLE: <one line, symptom not diagnosis>
PRECONDITIONS:
STEPS TO REPRODUCE:
EXPECTED:
ACTUAL:
ENVIRONMENT:
FREQUENCY / FIRST SEEN:
RECENT CHANGES:
SEVERITY (with reasoning, not just a label):
WORKAROUND:
ATTACHMENTS NEEDED:

And the report that comes out the other side:

TITLE: CSV export returns headers only when a date filter is applied PRECONDITIONS: Reports view, Q2 date filter applied before export STEPS TO REPRODUCE: 1) Open Reports 2) Filter Date range to Q2 3) Click Export CSV 4) Open the downloaded file EXPECTED: CSV contains the filtered rows ACTUAL: CSV contains headers only, zero data rows ENVIRONMENT: Chrome 131, macOS 15, app v4.2.1 FREQUENCY / FIRST SEEN: Every time a filter precedes export; first seen Monday RECENT CHANGES: NOT PROVIDED SEVERITY: Blocks the weekly reporting workflow; a workaround exists (export unfiltered, then filter in a spreadsheet) WORKAROUND: Export unfiltered, then filter in a spreadsheet ATTACHMENTS NEEDED: The empty CSV, a screenshot of the filter state right before export

Notice what didn't happen. Nothing about a database query, a caching layer, or an off-by-one in a filter clause, because none of that was in the answers and the prompt told the model to leave it out. That restraint is the entire point, and it's the part every reporter type below adapts for what they actually have on hand.

Bug report prompts when you're a developer reporting to your own team

You have the most raw material of any reporter type here: a stack trace, maybe a request ID, definitely a commit range you could check. The failure mode isn't missing data, it's skipping the translation step: pasting a stack trace into the ticket and assuming the shape speaks for itself. It doesn't. A teammate still has to reconstruct the preconditions and the exact click path from a trace that only shows what broke, not what led there.

Prompt 3: turn a stack trace into a repro-first report

I have a stack trace, not a repro yet. Don't write the ticket until
you've asked me what's missing.

STACK TRACE:
<paste>

Ask me, in order:
1. What action triggers this, as far as I can tell?
2. Does it happen on every attempt, or only some?
3. What's the earliest commit or deploy where you saw this?
4. Do you have a request ID, user ID, or log timestamp to correlate?

Then assemble a ticket: TITLE, PRECONDITIONS, REPRO STEPS, EXPECTED,
ACTUAL, STACK TRACE (verbatim, unedited), ENVIRONMENT, SEVERITY,
SUSPECTED COMMIT RANGE (mark as SUSPECTED, not confirmed). Do not
paraphrase the stack trace. Do not invent a line number that isn't in
the trace I gave you.

Prompt 4: bisect the commit range

Help me narrow down when this broke.

BUG: <one line>
LAST KNOWN GOOD: <commit/tag/date, or NOT PROVIDED>
FIRST KNOWN BAD: <commit/tag/date>

Ask me what I can quickly test (a deploy I can roll back locally, a
feature flag I can toggle, a dependency I can pin) before proposing a
bisection plan. Do not guess which commit caused it. Propose narrowing
steps in order and stop after each one to ask what I found.

Prompt 5: compress it for a Slack thread

Take this bug report:

<paste the assembled report>

Compress it to five lines for a Slack thread, in this order: what's
broken (one line), repro in one sentence, environment in one clause,
severity, and a placeholder link to the full ticket. Do not drop the
severity reasoning, just shorten it. Do not add anything not in the
source report.

Bug report prompts when you're a support agent relaying a customer's issue

A customer tells you what happened in their own words, in a chat or a ticket, and what you have is a narrative, not a repro: "it crashed when I tried to save," with no steps and no version, and often no idea there's a difference between the two. Your job has two parts a one-shot prompt skips entirely: pull out what's actually verifiable from the transcript, and know what to ask the customer next instead of guessing on their behalf.

Prompt 6: extract what's verifiable from a customer narrative

Here's a customer's own description of a problem, pasted verbatim.
Don't write a bug report from it yet. First, separate what's stated
from what's implied.

CUSTOMER MESSAGE:
<paste the ticket or chat text>

Produce two lists: FACTS (only what the customer actually said, quoted
or closely paraphrased) and GAPS (what a real bug report would still
need: exact steps, environment, frequency, when it started, what they
were doing right before). Do not fill the gaps with a guess.

Prompt 7: draft the follow-up questions

Using the GAPS list above, write the two or three questions I should
send back to this customer, in plain language they'll actually answer.
Avoid words like "reproduce," "environment," or "console." Ask for a
screenshot only if it would show something a description can't.

Prompt 8: assemble the internal escalation

Using the FACTS list and the customer's answers below, assemble an
internal ticket for engineering.

CUSTOMER'S ANSWERS:
<paste their reply>

Format: TITLE, CUSTOMER-FACING SUMMARY (one line, no jargon), REPRO
STEPS (as far as confirmed), EXPECTED, ACTUAL, ENVIRONMENT
(device/app version from the customer, or NOT PROVIDED), FREQUENCY,
ACCOUNT CONTEXT (plan tier only), SEVERITY. Do not include the
customer's name, email, or any account identifier other than the
support ticket ID.

Bug report prompts when you're QA and have steps but not environment detail

You already have the hardest part solved: a step-by-step repro a developer can follow, because finding one is your job. What QA reports tend to skip is environment pinning across every layer that matters (OS, browser or app build, device, feature-flag state), and an honest severity label instead of the "critical" that every bug you personally find tends to feel like in the moment.

Prompt 9: fill the environment gaps

Here's my repro:

<paste steps>

Ask me for whatever environment detail is missing before you finalise
this: OS and version, browser or app build number, device type,
account/plan tier if relevant, any feature flags or A/B variant I might
be in. If I don't know one of these, tell me exactly where to find it
rather than letting the field go blank.

Prompt 10: severity without inflation

Here's a bug I found: <describe it>

Before assigning severity, ask me: does this block the core task or is
there a workaround? How many users or what fraction of traffic could
hit this path? Is data being lost or corrupted, or just displayed
wrong? Then propose a severity level with one sentence of reasoning I
could defend to someone who disagrees. Do not default to "critical" or
"high" without that reasoning.

Prompt 11: what changed since the last passing run

This test passed in the last run and fails now.

LAST PASSING: <build/commit/date, or NOT PROVIDED>
FIRST FAILING: <build/commit/date>

Ask me what's different between the two runs that I can check quickly:
a merged PR list, a config change, a dependency update, test data
changes. Do not guess a cause. List the differences I confirm, ordered
by how likely each is to matter, and stop there.

How do you get a real bug report out of someone who isn't technical?

By asking in words they already use, and by treating "I don't know" as a complete, acceptable answer instead of pushing for a technical term they don't have. Someone who says "the app just closes" doesn't know the word "crash" is doing any work, and someone who says "it's broken" has usually noticed something specific if you ask about it the right way. The mechanism here is the same one covered in the post on getting ChatGPT to ask questions before it answers; this is that pattern, aimed specifically at a bug.

Prompt 12: the plain-language interview

I'm going to describe a problem with an app in my own words, not
technical terms. Before you write anything, ask me up to six questions
to understand it, one idea per question, no jargon (no "reproduce,"
"environment," "console," "log"). If I say "I don't know," accept that
and move to the next question rather than asking me to guess.

Cover: what I was doing right before, what I expected, what happened
instead, whether it's happened more than once, roughly when it started,
and what device or app I'm using. Wait for all my answers before
drafting anything.

Prompt 13: screenshot-first triage

I have a screenshot of the problem, not a technical description.

Based on what I describe from the screenshot, ask me only what the
image can't tell you: what I clicked right before, whether this is the
first time, and what I expected instead. Don't ask for anything a
screenshot would already show, like exact error text if it's visible.

WHAT'S IN THE SCREENSHOT: <describe what you see>

Prompt 14: assemble from plain-language answers

Using only my answers above, in my own words, write this as a bug
report a developer can act on. Translate my language into the report's
structure, but do not add technical detail I didn't give you: no
version numbers, no error codes, no mechanism. Where you had to guess
which button or screen I meant, mark it INFERRED and say why.

Format: TITLE, WHAT THE USER WAS DOING, WHAT THEY EXPECTED, WHAT
HAPPENED INSTEAD, HOW OFTEN, DEVICE/APP (as given), NOT PROVIDED for
anything missing.

What does an external vendor or open-source maintainer need that your own team doesn't?

A minimal reproducible example, and building one is its own skill, separate from writing the report around it. An internal ticket can lean on shared context: your teammates know the codebase, the data shapes, and the deploy history. An external report has to survive contact with a stranger who has none of that, which means stripping the problem down to the smallest thing that still breaks, with no proprietary logic and ideally no real data at all.

Prompt 15: build a minimal reproducible example

Help me build a minimal reproducible example (MRE) for an external bug
report. Do not write the final report yet.

Ask me:
1. What's the smallest piece of code, config, or steps that still
   triggers this, as far as I've tested?
2. What have I already removed and confirmed the bug survives without?
3. Does this depend on my data, or would it happen with dummy data?
4. Which library/tool version and OS am I on?
5. Is there a public repo or sandbox link I can share, or do I need to
   build one from scratch?

Then, using only my answers, produce a step-by-step plan for stripping
my real project down to the smallest file(s) that reproduce this,
starting from what I already ruled out.

Prompt 16: reduce it further

Here is my current reproduction: <paste code/config/steps>

Suggest ONE thing to remove or simplify next that is most likely to
still reproduce the bug. Do not suggest multiple changes at once. After
I tell you whether the bug survived, suggest the next single reduction.
Stop when I confirm removing anything further makes the bug disappear.

Prompt 17: strip identifying information before it leaves the building

Review this bug report and reproduction steps before I send them to an
external vendor or public issue tracker.

<paste the draft report and repro code>

Flag anything that looks like: a real customer name, email, or account
ID; an API key, token, or credential, even partially shown; an internal
URL, hostname, or service name; proprietary business logic not needed
to trigger the bug. For each flagged item, suggest a generic
replacement that keeps the report reproducible without it. Do not
remove technical detail that is required to reproduce the bug.

Prompt 18: assemble in vendor-issue-template shape

Using only the reduced reproduction and the answers already given,
write this as an external bug report for <vendor/repo name>.

Follow the shape their own issue template expects: a one-line summary,
environment (library version, OS, runtime version), the minimal
reproduction (code block or numbered steps), expected vs actual, and a
link to a live reproduction if I have one. Do not add severity
language. Do not speculate about the vendor's internal cause. If a
field truly has no answer, write NOT PROVIDED.

Is it safe to paste customer data into a bug-report prompt?

Not into a consumer AI surface, and the reason is more specific than "be careful." The moment a real customer's name, email, account ID, an API key, or a screenshot of production data goes into ChatGPT or Gemini to help write a report, that content can become part of what the vendor keeps, on a timeline you don't control and can't always undo by deleting the chat afterward.

Check a vendor's own retention documentation rather than trusting a paraphrase, including this one. OpenAI's US privacy policy, updated May 18, 2026, says it will remove personal data within 30 days of a deletion request, with one exception: content that has already been de-identified and disassociated from your account when you allow OpenAI to use it to improve its models (openai.com/policies/us-privacy-policy, accessed August 27, 2026). Once that has happened, deleting the chat afterward does not pull the data back out.

Google's Gemini Apps Privacy Hub, last updated August 10, 2026, is blunter about the human-review path: chats a reviewer looks at are not deleted when you delete your activity, and are instead retained for up to three years (support.google.com/gemini/answer/13594961, accessed August 27, 2026). The same page tells you not to enter confidential information you wouldn't want a reviewer to see.

Neither policy is unusual and neither is hidden. Both are published, dated, and easy to check, which is the point: this isn't a risk you have to take a vendor's word on, from us or anyone else. Read the current page for whichever tool you're about to paste customer data into, on the day you're about to do it, because these pages get updated.

Why will a model invent an error code if you let it?

Because a fluent, specific-sounding answer is what the model is optimised to produce, and "I don't know, you didn't tell me" is not the fluent option. Ask a vague question and a capable model will often supply an error code, a version number, or a plausible mechanism that nobody actually gave it, stated with exactly the same confidence as the facts you did provide. The sibling post on why ChatGPT makes things up covers the mechanism behind that in general; here it costs a specific kind of afternoon.

In a bug report, this is not a harmless quirk. An invented error code sends someone down the wrong logging query. An invented "introduced in version X" sends them to the wrong commit range. A guessed mechanism, phrased as a fact, gets copied into the ticket and treated as established, and now a real engineer spends real time confirming or ruling out something the reporter's tool made up.

Every prompt on this page tells the model to write NOT PROVIDED rather than infer, and to tag anything it does infer with a clear label and a reason. That instruction is not decoration. Left out, the assembly step quietly fills every blank you left with something that reads like an answer.

Prompt 19 is the one-line add-on that makes this the default rather than something you have to remember for every report.

Prompt 19: the enforcement line

Append this line to the end of any bug-report prompt above:

Never invent a version number, error code, file name, or mechanism I
did not give you. If a field has no answer, write NOT PROVIDED. If you
must infer something from context to make the report readable, tag it
as INFERRED and say what you inferred it from.
Free Chrome Extension

Stop rewriting prompts. Start shipping.

Works with ChatGPT, Claude, Gemini, Grok, Midjourney, Ideogram, Veo3 & Kling. 5.0★ on the Chrome Web Store.

Create An Account

One checklist before you send any AI-written bug report

Run the assembled report past five checks before it leaves your hands. Does every NOT PROVIDED still say NOT PROVIDED, or did a later edit quietly fill one in? Does every INFERRED tag still carry its explanation? Would a stranger who has never seen your app be able to follow the repro steps without a single follow-up question? Is the severity label something you could defend out loud, rather than just what felt urgent at the time? And did you redact anything real before it went into the prompt?

That last check deserves its own habit, not a one-time read. The prompt hygiene checklist covers the ten-second version of most of this for any prompt, not just bug reports, and is worth running on the interrogation prompt itself before you send it the first time. Developers pushing further into the actual fix, rather than the report, will find the next step covered in 30 AI prompts for debugging.

None of this replaces the work of actually fixing the bug, and no prompt template does either. What a saved template is genuinely useful for is the part that decays under deadline pressure: the eight-question interrogation and the assembly format above are long enough that people shorten them by hand until the discipline quietly disappears, usually right when a release deadline makes the questions feel optional. Keeping the exact wording in a prompt library, rather than retyping an abbreviated version each time, is the boring difference between the first bug report you file this month and the tenth.

Frequently asked questions

Free Chrome Extension

Stop rewriting prompts. Start shipping.

Works with ChatGPT, Claude, Gemini, Grok, Midjourney, Ideogram, Veo3 & Kling. 5.0★ on the Chrome Web Store.

Create An Account