v1.4.0Triage that admits when there's nothing to find
Guides
  • Rhys Adams

How to write bug reports an AI coding agent can actually fix

"Button doesn't work" is a bad bug report for a human. For an AI coding agent it's a dead end. The agent can't ask the reporter what they meant, can't shake the page until the bug falls out, and can't guess which of your 400 buttons is broken.

What agents can do, given a precise description of what broke and where, is read the code fast, write the fix and open a pull request. Everything upstream of that has to arrive with the report. In practice that means five things.

#What a fixable report carries

The exact element, first. Not "the checkout button" but the actual node: selector, test id, visible label, and ideally the component that rendered it. An agent goes from data-testid="cart-submit" to the right file in seconds. From a described screenshot it greps around and guesses.

Then the actions that led up to it, in order. Clicked "Add to cart", typed 3 in the quantity field, clicked "Checkout". Most UI bugs are state bugs, so the third click only fails after the second edit. An ordered trail also answers the first question anyone debugging asks: what changed right before it broke?

Then the failure itself. The console error with its stack, and the network request that went wrong with method, path and status. POST /orders returned 500, then a TypeError reading total is a diagnosis. Without it, an agent will cheerfully fix a plausible bug that isn't yours. I've watched this happen. The fix was clean, well tested, and for a code path the reporter never touched.

Fourth, the environment, and specifically the deployed release. Browser and viewport matter, but release is the one everybody skips. A bug that only exists on v1.4.2 is a bisect, not a hunt. If reports carry the release, "when did this start" becomes a lookup.

And last, proof: a test that fails against the bug and passes when it's fixed. This is the strongest thing a report can contain. It pins the agent to the actual defect, and it turns "the agent says it's fixed" into "the fix is verified."

#Nobody writes reports like this, and that's the point

No reporter is going to type selectors and network traces into a form. They don't know which release is deployed. They saw a symptom; the rest of the context lived on the page at the moment they saw it, and by the time anyone reads the ticket it's gone.

So stop asking people to write it. Capture it. At click time, the element, the trail, the console, the failed request and the release are all sitting right there. The reporter's whole job should be pointing at the thing and saying what they expected instead.

This is the problem Rebase exists for. One script tag, and every report arrives with the element pinned, the recent actions and errors attached, and a fix bundle your agent can pull over MCP, failing test included. The agent applies the fix and raises the PR with your credentials, not ours.

#Make the repro executable

If you only adopt one habit from this post, make it this one. A repro that's a Playwright test never goes stale and never gets misread:

test("order total updates on quantity change", async ({ page }) => {
  await page.goto("/cart");
  await page.getByTestId("qty-input").fill("3");
  await expect(page.getByTestId("cart-total")).toHaveText("$36.00");
});

A red test is remarkably hard to argue with, whether the thing reading it is an agent or a tired human at 5pm.

That's the whole recipe. Element, ordered trail, real error, release, failing test. Capture it when the click happens, because nobody can reconstruct it afterwards, and hand it to the agent whole. Then review the PR instead of the symptom.

One script tag. Every report ready to fix.

Free forever on one site. No card, no extension, no dashboard to learn.