← Readback blog
Engineering · June 2026

The night prod went down: a Prisma foot-gun

This one’s a postmortem, told straight — because building in public means the outages too.

What happened

A new feature added a database column with a unique constraint. On every deploy, the container boots by running prisma db push to sync the schema, then starts the server. But db push refuses to add a unique constraint without an explicit --accept-data-loss flag — so the push exited with an error. The boot chained the two commands with &&, so when the push failed the server never started. The container restart-looped all night. Quiet 502s until morning.

The fix everyone reaches for is the wrong one

The obvious move is to add --accept-data-loss to the boot. We didn’t. That flag once silently dropped data on a sister project, and a compliance tool is the last place you want a deploy quietly destroying rows. The ban stays.

Resilience instead

Instead we made the boot degrade gracefully: if the push refuses a change, log it loudly and start the server on the existing schema anyway. The pending change just waits to be applied deliberately — a controlled one-off, or a real migration — instead of taking the whole app down with it.

A refused migration should degrade, not detonate.

The cheap check we skipped

One more lesson, free of charge: run your type-checker before you push. A few days earlier, an editor “helpfully” turned a straight quote into a curly one inside a string literal and broke a build the same silent way. A two-second tsc --noEmit would have caught both. It’s in the pre-push routine now.

Readback — charter quoting with the compliance gate built in

Forward a charter request; get a compliant, formula-annotated quote — but only if the assigned crew is legal.