Skip to content
RequirementsFirst
Go back
acceptance-criteria

Acceptance criteria that actually prevent bugs (with 12 worked examples)

By Arun Mehta · 25 May 2026 · 11 min read


Open any backlog. Read the acceptance criteria on five stories.

You’ll see lists like this:

This is the acceptance criteria style that 80% of BAs write. It looks thorough. It will not catch a single bug that wouldn’t have been caught anyway.

The reason is simple: these criteria describe what the feature does, not what could go wrong. They are a checklist for the happy path. The bugs that ship to production live in the unhappy path, the boundary conditions, the race conditions, and the assumptions that nobody wrote down because they felt obvious.

Acceptance criteria that actually prevent bugs are different. They name the failures.

The frame: write criteria as “this won’t happen”, not “this will happen”

The shift is small but powerful. Instead of:

User can save the form.

Write:

Saving the form will not succeed if any required field is blank, and the error will name which field is blank.

The first version describes a behaviour. The second version describes a behaviour plus the failure mode it eliminates. The first will pass QA. The second will catch the bug where the form saves silently with a blank field, leaves a corrupted record in the database, and breaks a downstream report three weeks later.

The shift is from “describe what happens” to “describe what won’t happen”. Every criterion should answer the question: if this is missing, what bug ships?

The twelve examples

Twelve common patterns where standard acceptance criteria miss the bug, and the rewritten version that catches it. These are genericised from real production examples.

Example 1: The silent save failure

Standard criteria:

Criteria that prevent bugs:

The standard version passes QA. The detailed version catches: silent failures, lost-input rage-quits, and the bug where validation runs but the record is still partially written.

Example 2: The optimistic UI lie

Standard criteria:

Criteria that prevent bugs:

Standard version passes when QA clicks the button on a happy day. Detailed version catches: optimistic UI lying to the user that their data saved when it didn’t, double-submits creating duplicate records, and the silent timeout where users assume success and walk away.

Example 3: The empty state nobody designed

Standard criteria:

Criteria that prevent bugs:

Standard version passes for users with orders. Detailed version catches: blank dashboard panels for new users that look like broken software, infinite spinners that never resolve, and the “is this site working?” support ticket.

Example 4: The permission edge case

Standard criteria:

Criteria that prevent bugs:

Standard version catches the basic positive case. Detailed version catches: privilege escalation bugs (admin of one team deletes another team’s data), orphaned records, and the worst-case scenario where a “deleted” record still appears in stale views.

Standard criteria:

Criteria that prevent bugs:

Standard version passes if QA searches one term. Detailed version catches: case-sensitivity bugs that confuse users, whitespace bugs from copy-paste, the bug where empty search returns nothing (so the page looks broken), and the “no results” state that looks like a bug.

Example 6: The date that crosses time zones

Standard criteria:

Criteria that prevent bugs:

Standard version works on the developer’s machine. Detailed version catches: the cross-timezone bug that makes Indian customers see “yesterday’s” orders as today’s, off-by-one date range bugs, and the silent timezone mismatch that breaks finance reports at month-end.

Example 7: The slow response that pretends to be fast

Standard criteria:

Criteria that prevent bugs:

Standard version is a wish. Detailed version is testable, names the network conditions, and catches the bug where the page “loads” in 2 seconds but the data takes 8.

Example 8: The audit trail that lies

Standard criteria:

Criteria that prevent bugs:

Standard version satisfies the compliance checkbox. Detailed version catches: the missing-actor bug (“system” did it, but who started the workflow?), the “we logged it but you can’t query it” bug, and the bulk delete that destroys 10,000 records but leaves one audit entry.

Example 9: The notification that gets lost

Standard criteria:

Criteria that prevent bugs:

Standard version passes when the email arrives. Detailed version catches: silent email failures, missing context in the email, broken deep links, and the opt-out that wasn’t respected (GDPR/privacy violation territory).

Example 10: The first-time-user trap

Standard criteria:

Criteria that prevent bugs:

Standard version assumes the user knows what to do. Detailed version catches: the dropoff bug where new users land on an empty dashboard and bounce, the onboarding restart loop, and the legal compliance failure where terms acceptance can be skipped.

Example 11: The integration that silently breaks

Standard criteria:

Criteria that prevent bugs:

Standard version assumes the integration works. Detailed version catches: silent sync failures that leave data inconsistent between systems, the lost-records bug when the CRM is briefly down, and the operations team finding out about sync failures from angry customers.

Example 12: The error message that helps no one

Standard criteria:

Criteria that prevent bugs:

Standard version passes because errors exist. Detailed version catches: useless error messages that drive support tickets, missing reference IDs that make support impossible, and the security bug where stack traces leak system internals to the user.

How to actually use this

You don’t need to write twelve criteria for every story. The point is the frame. For each story you write, ask: what could go wrong here that wouldn’t be caught by “the feature works”?

The questions to walk through:

You’ll find that three or four sharp criteria from this list will replace ten weak ones, and prevent more bugs than the long version did.

The discipline

The discipline is to stop writing acceptance criteria that describe the happy path. The happy path is what the feature does. The criteria are for the unhappy paths — because the unhappy paths are where the bugs ship.

If your criteria don’t make the engineering team uncomfortable, they’re not catching enough.


The next piece in this series breaks down the 3-question framework for handling “just do what I said” stakeholders. Subscribe below to get it.


Share this post:

Get new posts by email

Notes on requirements, problem-framing, and the BA craft. No spam, unsubscribe anytime.


Previous Post
Most stakeholder conflicts are authority disputes, not requirements disputes
Next Post
How I use Claude to interrogate my own requirements before showing them to engineering