agent ran db:seed after the migration but the seed assumed the old schema - it wiped the freshly migrated data
Fixes data loss from running db:seed after a migration when the seed still assumes the old schema. Use it when a seed truncated or overwrote freshly migrated tables. Key trigger: the seed file references columns or tables the migration changed.
TL;DR
Restore the wiped data from the pre-migration backup first, then update the seed to the new schema before running it again. Seeds written against the old schema can truncate or overwrite tables the migration just built. Going forward, version seeds alongside migrations and make them idempotent, so re-running a seed is always safe.
agent ran db:seed after the migration but the seed assumed the old schema - it wiped the freshly migrated dataSteps
- Stop everything and assess. Check whether the seed truncated tables, deleted rows, or just inserted rows that now violate the new schema.
Expected: you know exactly which tables lost data and which are untouched.
- Restore the wiped data from the pre-migration backup into the migrated schema. If no backup exists, check the migration's own staging tables and logs before declaring the data unrecoverable.
Expected: row counts match the backup.
- Update the seed for the new schema: new column names, new required columns, new tables, removed tables.
Expected: the seed file references only objects that exist after the migration. A dry run against a staging copy proves it.
- Make the seed idempotent. Use upserts or find-or-create keyed on a natural key, and never TRUNCATE tables that hold migrated production data.
Expected: running the seed twice produces the same database state.
- Re-run the seed in a transaction on a staging copy first, then on the target.
Expected: the seed completes, the migrated data is intact, and row counts are as expected.
Use this when
- A seed ran after a migration and data disappeared.
- The seed references columns or tables that no longer exist.
- A seed overwrote rows the migration just moved or created.
- An agent runs db:seed as a routine post-migration step without checking it.
Not for this skill when
- The seed fails without touching any data (pure schema mismatch, nothing lost).
- The migration itself wiped the data (fix the migration, not the seed).
- The reseed is intentionally destructive, like a dev environment reset.
Variant phrasings
- db:seed wiped migrated data
- seed assumed old schema after migration
- make db seeds idempotent
- seed truncated tables after migrate
Why it happens
Seeds and migrations evolve on different schedules. A seed written months ago encodes the old schema's shape; run after a migration, its TRUNCATE and INSERT statements hit the new tables with old assumptions and destroy the data the migration just moved. Nobody owned the seed, so nobody updated it.
Edge cases
- Rails db:seed is not transactional by default. Wrap it in a transaction so a mid-seed failure does not leave a half-seeded database.
- Some seeds are meant to reset data (dev and test environments). Gate those behind an explicit environment check so they can never run against migrated production data.
- If there was no backup, this incident is the argument for mandatory pre-migration snapshots. Add that to the runbook now, while it hurts.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_uebCCg5ihIoLn6LWQ3xrbQ
Maintainer review
No maintainer verification is recorded for this version.
This records the version a maintainer checked. It does not assert that the version is the latest upstream release.