dánwòdánwò

Fault matrix

Common findings

The bugs the fault matrix finds most often, what each looks like, and how to fix it.

Most matrix failures come from a handful of patterns. Each one below shows the failing trial, what went wrong, and the usual fix.

A webhook handled twice

FAIL  duplicate on webhook checkout.session.completed
        invariant: expected 1000 to be 500

What happened. Providers deliver webhooks at least once, so the same event can arrive twice. Your handler granted the credits both times.

The fix. Store each event's id when you handle it, and skip an id you've seen:

src/webhooks.ts
const handled = new Set<string>()

export function onCheckoutCompleted(event: { id: string }, grant: () => void): void {
  if (handled.has(event.id)) return

  handled.add(event.id)
  grant()
}

In production, keep the ids in your database, in the same transaction as the work.

A payment made twice

FAIL  double-submit on POST /buy
        invariant: expected 2 to be 1

What happened. The user clicked Pay twice, or the page sent the request twice. Your app created two payments.

The fix. Send Stripe an idempotency key that's the same for both requests, such as the order id. Stripe returns the first payment instead of making a second one.

An answer lost after the work was done

FAIL  reset-after on POST api.stripe.com/v1/payment_intents
        invariant: expected 2 to be 1

What happened. Stripe took the payment, but the connection dropped before your app got the answer. Your app retried, and paid again.

The fix. The same as a double submit: an idempotency key on every call that moves money, so a retry is safe.

A lost commit

FAIL  reset-after on COMMIT (postgres)
        invariant: expected 0 to be 1

What happened. Postgres committed the order, but your app never heard back. It showed an error, or tried again and created a second order.

The fix. After a lost commit, check whether the row exists before writing it again. Or make the write idempotent with a unique key, such as an ON CONFLICT clause.

A failure shown as success

FAIL  status 500 on POST api.resend.com/emails
        invariant: expected 0 to be 1

What happened. Sending the confirmation email failed, but the page still said "Check your inbox".

The fix. Treat the provider's error as an error: retry it in the background, or tell the user it didn't go out.

Next

On this page

Run it on every pull request

A GitHub check and one comment per pull request, with the flight records attached.

Set up CI