Use AI to Write a Bug Report: Turn Vague Complaints into Reproducible Tickets

Turn 'the app is broken' into a structured ticket with steps, expected vs actual, severity, and the clarifying questions to ask first — with a copy-ready prompt and a real severity scale.

TL;DR

Paste the user’s verbatim complaint plus whatever environment data you have into the prompt below. AI is reliable at one job: reshaping a vague message into the standard ticket fields (title, numbered repro steps, expected vs actual, severity, environment) and drafting the clarifying questions you should ask before filing. It is unreliable at guessing root cause — so the prompt explicitly asks it to flag and strip any speculation. As of June 2026, Claude (Opus 4.7 or the cheaper Sonnet 4.6) tends to hold a fixed output schema more consistently than other models, which is what you want for a repeatable triage workflow.

The task

Support inbox: “It’s broken.” Five words, zero context, zero reproduction steps. Engineering can’t act on that. You need a ticket with a searchable title, numbered steps, expected versus actual behaviour, a justified severity, and the environment. The harder, higher-value part is the clarifying questions to ask the user before filing, so the ticket does not bounce back marked “needs more info” — the single most common reason a report stalls.

When AI helps, and when it does not

AI is genuinely good at two things here: structuring a messy message into the standard report shape, and writing tight clarifying questions that pin down ambiguity. It is bad at diagnosing. If the model confidently writes “this is a state-management race condition,” delete that line. The ticket’s job is to describe observed behaviour precisely enough that an engineer can reproduce it; the engineer owns the diagnosis. A bug report that ships a wrong root-cause guess is worse than one that ships none, because it sends triage down the wrong path.

What to feed the AI

  • The user’s verbatim message (paste it raw, do not paraphrase — phrasing is evidence)
  • Device, OS, app version, and browser (pull from email headers, request logs, or the user’s signature if possible)
  • Whether you can reproduce, partially reproduce, or cannot reproduce it
  • Repro steps, if you have any
  • Account state, if relevant: free or paid, locale, plan changed recently, beta flags on
  • Your team’s severity scale, with definitions (so the model maps to your labels, not generic ones)

Severity vs priority — keep them separate

The most common triage mistake is collapsing these two into one number. They are independent axes, and the cleanest teams set them separately:

AxisQuestion it answersWho owns it
SeverityHow badly does this break the product, technically?Whoever is closest to the technical evidence (QA / reporter)
PriorityHow soon must this be fixed, given the business?Whoever owns the business context (PM / lead)

The classic example: a crash-on-launch bug in a feature nobody uses is high severity but low priority; a one-pixel misalignment on the checkout “Pay” button is low severity but high priority because it dents conversion. Tell the AI to assign severity (the part it can reason about from the report) and to leave priority to a human.

A common four-level scale, as used by many QA teams:

LevelMeaningExample
S0 / CriticalData loss, security exposure, or total outage for many usersLogin broken for all users; payment double-charges
S1 / BlockerApp crashes or a core flow is fully blocked, no workaroundCheckout button does nothing on every device
S2 / MajorA significant feature fails, but a workaround existsExport to PDF fails; user can still export CSV
S3 / MinorCosmetic or low-impact issueMisaligned label; typo in a tooltip

Copy-ready prompt

Convert this user complaint into a bug report.

User message (verbatim):
"""
[paste]
"""

Device / OS / version / browser: [paste or "unknown"]
Repro status: [can repro / partial / cannot]
Repro steps if any: [paste]
Account state: [free / paid / locale / recent changes]
Our severity scale: [paste your S0-S3 definitions]

Return:
1. Title — specific, scannable, includes the feature area
2. Steps to reproduce, numbered, starting from a clear entry point
3. Expected behaviour
4. Actual behaviour (observed only, no inferred cause)
5. Severity (S0-S3) — with one line of reasoning tied to user impact
6. Environment — device, OS, version, browser, region
7. Clarifying questions to ask the user before filing — 3 max, prioritised, each answerable in one line
8. A "do not assume" callout — list any root-cause speculation you were tempted to add, so I can confirm it stays OUT of the ticket

Rules: Do not invent missing facts. Where a field is unknown, write [UNKNOWN: ask user]. Do not assign priority — that is a human call.

For mobile bugs, add a line: Add an iOS / Android divergence check — does the same repro happen on the other OS? If you triage in volume, ask the model to also output a compact JSON block with the same fields so it can drop straight into Linear, Jira, or GitHub Issues.

How to check the output is usable

  • Title is searchable: includes the feature area, never “app is broken”
  • You can follow the numbered steps and reproduce the bug yourself
  • Expected and actual are both stated — engineering cannot work with only one
  • Severity carries one line of reasoning, not just a label
  • Clarifying questions are answerable by the user in a single line each
  • The body contains no root-cause speculation (check the “do not assume” callout did its job)
  • Environment is captured; a bug that only appears on iOS Safari will never reproduce on Windows Chrome

Common mistakes

  • Filing vague reports. Engineering bounces the ticket and the user gets more frustrated while it round-trips.
  • No expected vs actual. The number-one “needs more info” reason. Both are non-negotiable.
  • No severity assigned. The ticket sits in triage limbo with nothing to sort it by.
  • Letting AI guess root cause. It reads as helpful and quietly derails the engineer.
  • Skipping clarifying questions. Asking before filing is faster than a multi-day comment thread after.
  • Dropping the environment. OS-specific bugs get assigned to the wrong team and stall.

FAQ

  • Which model should I use? As of June 2026, Claude Sonnet 4.6 is a strong, low-cost default because it holds a fixed output schema consistently across many tickets; reach for Opus 4.7 on long, tangled threads. GPT-5.5 works well too — pin the schema in your prompt and keep it identical every run so tickets stay comparable.
  • What if the user is hostile? Reply gently before you clarify. Tone decides whether they answer your questions at all, and unanswered questions mean a stalled ticket. See Customer service reply.
  • Engineering disagrees with my severity? Defend it with user-impact reasoning, not feature importance. “All users on launch” beats “this is my favourite feature.”
  • Should AI categorise the bug area? Yes, if your taxonomy is consistent and you give the model the list. If categories are fuzzy, let a human triage and use AI only for the writing.
  • Can I batch many reports at once? Yes. Ask for the JSON output and feed several complaints in sequence, but spot-check the first few — a model that drifts on schema will quietly desync your fields.

Tags: #AI writing #Product startup #Bug report