agent deleted old migration files thinking they were stale - now new environments cant bootstrap
Recovery when an agent deleted old migration files thinking they were stale, so new environments cannot bootstrap: restoring the files and setting the rule that applied files are never deleted. Use when fresh databases fail to migrate from zero. Not for files that were never applied anywhere.
TL;DR
Old migration files are not stale: they are the only path from an empty database to the current schema, and every environment's history references them. Restore the deleted files from version control, prove a fresh database bootstraps from zero, and set the team rule: applied migration files are immutable and never deleted. Squash deliberately instead of deleting casually.
The query
agent deleted old migration files thinking they were stale - now new environments cant bootstrapUse this when
- Deleted migration files broke new environment bootstrap
- Fresh database cannot migrate from zero
- Old migration files thought to be stale
- An agent pruned migration history
Not for
- Files that never applied anywhere (deleting those is safe, with care)
- A deliberate squash (do the squash properly, keep the old files until every environment passes them)
- Corrupt migration files (fix or replace them, do not just delete)
Steps
1. Restore the deleted files
git log --diff-filter=D --name-only -- [migrations dir]/
git checkout [commit before deletion] -- [migrations dir]/Expected output: the files are back with their original content. Restore all of them: a partial restore leaves a different hole.
2. Prove fresh bootstrap works
On an empty database, run the full migration chain from zero:
alembic upgrade head(or the tool's equivalent). Expected output: the chain completes and the schema matches production. This is the test the deletion broke; it must pass now.
3. Check every environment's history still resolves
For each environment (prod, staging, dev databases), verify its recorded versions all have files: alembic history, flyway validate, or the tool's check. Expected output: no "missing revision" or "not resolved locally" errors anywhere.
4. Set the immutability rule
Applied migration files are never deleted, period. The runbook states it; code review enforces it; a CI check can flag deletions under the migrations directory.
Expected output: the next "cleanup" instinct meets a rule that says no.
5. Squash deliberately when history gets long
If the real complaint is a long chain, do a proper squash: new baseline migration, old files kept until every environment has passed the squash point, schema equivalence proven on scratch. Expected output: a shorter chain achieved without breaking any environment's history.
Tool compatibility
alembic, flyway, django, rails, prisma, dbmate: every tool needs its history files to bootstrap fresh databases.
Variant phrasings
deleted old migration files new environments cant bootstrap
Steps 1 and 2: restore from git, prove fresh bootstrap from zero.
migration files deleted thinking stale
Step 4: applied files are immutable. "Stale" is not a concept that applies to migration history.
squash vs delete old migrations
Step 5: squash deliberately with equivalence proof; never delete casually.
Why it happens
Migration files serve two masters: existing databases (which need the files their history references) and new databases (which replay the whole chain from zero). Deleting "old" files breaks both: existing environments lose resolvable history, and new environments have no path to the current schema. The files look stale because they already ran; that is exactly what makes them load-bearing.
Edge cases
- A partial restore (some files back, some still missing) produces confusing half-errors: restore everything the deletion removed, then verify.
- If the deletion also shipped to production's history (someone "cleaned" prod), the restore must happen before any new migration runs there, or the chain forks.
- Files that never applied anywhere are genuinely deletable: verify "never applied" against every environment's history table, not just prod.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_lmdvRslYdJ03zkddWtrDyQ