A vibe coder I follow lost two days of customer data last weekend.
Not from a hack. Not from a hardware failure. From a single AI-generated migration that a senior engineer would have caught in 10 seconds.
If you're shipping with Claude, Cursor, Copilot, or any agent that touches your schema, you need to read this before you run another migrate command.
What actually goes wrong
AI is genuinely good at writing application code. It pattern-matches against millions of similar codebases and produces plausible code fast. For most things — components, handlers, glue logic — that's enough. If it's wrong, you re-render. You re-run. You ship a fix.
Database migrations are different. They have one property the AI quietly ignores: they execute exactly once, and the wrong sequence is unrecoverable without a backup.
Three failure modes I've now seen in the wild:
1. Silent column drops. The AI "improves" a migration by removing what it thinks is a dead column. The column had three months of customer data. The migration runs in production. The column is gone. You restore from backup and lose everything written since the snapshot.
2. Type changes that truncate. Convert a TEXT to VARCHAR(255)? Sure, the AI will do that. The 12 customers whose addresses were 280 characters? Their addresses are now 255 characters and the suffix is in the trash bin.
3. Backwards-incompatible renames mid-deploy. The AI renames user_email to email because "it's cleaner." The old version of your app, still running on half your boxes during the rolling deploy, throws 500s for 90 seconds. Customers see them.
None of these are bugs in the AI. The AI did what you asked. The bug is that you're using AI like a junior dev who needs review, except the review never happened.
Why migrations are the worst case for AI
Most AI failures are recoverable. You ship a bad component, you redeploy the previous version. You commit a typo, you push a fix. The blast radius is contained to "the next 30 seconds of users."
Migrations break that pattern in three ways:
- They modify shared, mutable state. Code is reproducible from git. Data is not.
- They run irreversibly. "Down migrations" exist in theory. In practice, they don't roll back data deletes.
- They touch every customer simultaneously. A bad migration is not a 5% bug. It's a 100% bug across your entire customer base in one transaction.
The combination — irreversibility, shared state, fanout — is exactly the property AI shouldn't be trusted with unsupervised. And yet it's the one most vibe coders trust it with the most, because writing migrations is boring and AI is happy to do boring work.
What "review" actually means for migrations
When I say "don't let AI run migrations unreviewed," I don't mean "skim the diff before clicking yes."
I mean this checklist, every time:
-- Before running ANY AI-generated migration, answer:
-- 1. What columns/tables does this DROP? (grep for DROP, ALTER ... DROP)
-- 2. What types does this CHANGE? (ALTER ... TYPE)
-- 3. What constraints does this ADD that could fail? (NOT NULL on existing column, UNIQUE)
-- 4. What renames does this do? (RENAME TO, RENAME COLUMN)
-- 5. Does this run in a transaction? (BEGIN / COMMIT?)
-- 6. Could this lock the table for more than 1 second on production data?
If you can't answer all six in 30 seconds, the migration isn't reviewed. It's been glanced at. Those are not the same thing.
Concrete defenses for vibe coders
You don't need to become a DBA. You need three guardrails.
1. Always run migrations on a production-clone first
Most managed Postgres providers (Supabase, Neon, Render) let you branch the database. Branch it, run the migration on the branch, run smoke tests. If it explodes, it explodes on the branch.
# Neon example
neon branches create --name migration-test
neon migrations apply --branch migration-test
# run tests against the branch
neon branches delete migration-test # if it worked, apply to main
Five minutes of work. Catches 90% of disasters.
2. Forbid destructive operations in CI
Add a check to your migration pipeline that fails if the SQL contains certain keywords without an explicit override:
# In your CI, before applying migrations:
if grep -E "DROP COLUMN|DROP TABLE|ALTER.*TYPE" migrations/*.sql; then
echo "Destructive migration detected. Set MIGRATION_DESTRUCTIVE_OK=1 to override."
[ "$MIGRATION_DESTRUCTIVE_OK" = "1" ] || exit 1
fi
Now every destructive migration requires a deliberate human decision. The AI can't override it. You can't accidentally merge it. The friction is the feature.
3. Always back up immediately before applying
Every migration runner should have a "snapshot before apply" step. If it doesn't, write one:
# Before migrate:
pg_dump $DATABASE_URL > backup-$(date +%s).sql.gz
# Now apply:
npm run migrate
The backup is cheap. The peace of mind when something breaks is not.
The non-obvious takeaway
The actual lesson from every "AI broke production" incident isn't "AI is dangerous." It's "AI shifted the bottleneck from writing code to reviewing code, and most teams haven't noticed."
In 2024, your bottleneck was: how fast can I write this. Reviews were small because changes were small.
In 2026, your bottleneck is: how fast can I review what the AI wrote. The volume of AI-generated code is so high that review-quality is the new code-quality. If your review process for migrations is "looks plausible, ship it" — you have no review process.
The vibe coders who survive 2026 won't be the ones who stop using AI. They'll be the ones who built systems that compensate for unreviewed AI output — branched databases, destructive-op guards, automatic backups. They'll trust the AI for code and distrust it for state changes, and they'll build infrastructure that makes that distrust easy.
The business angle
If you're shipping a SaaS, your data is your business. Application code can be rewritten in a weekend. A corrupted customer table cannot. Every hour of "missing data" you have to explain to a B2B customer is an hour your churn risk goes up. The teams I see selling into enterprise in 2026 treat their migration pipeline as a product feature — not a CI afterthought — because their buyers ask about it.
If the answer to "how do you protect against bad AI-generated migrations" is a blank stare, that's a deal-killer. If the answer is "branched DB, destructive-op guard, automatic snapshot, human approval for destructive ops" — that's a wedge.
What to do today
Go check your last three migrations. Were they AI-generated? Were they reviewed against the six-point checklist above? If not, your runway from "vibe coder" to "outage" is shorter than you think.
Then add the three guardrails above to your project. It's an afternoon of work. The day you don't lose your customers' data because of it, you'll thank past-you.
Follow LayerZero for security and infrastructure that vibe coders can actually use. Next: why backups you can't restore are worse than no backups at all.
Top comments (0)