alembic error: Can't locate revision identified by 'a1b2c3d4' after deleting a migration file
A fix for alembic's "Can't locate revision identified by" error after a migration file was deleted: how to find which surviving file still references the missing revision id, and whether to restore the file, recreate a stub, or repoint the chain. Use when alembic commands fail because a down_revision points at a deleted file. Not for multiple-heads errors or databases whose alembic_version is simply behind.
TL;DR
Some surviving migration still lists the deleted file's id in its downrevision, so the chain is broken. Search every revision file for that id, then either restore the deleted file from version control, recreate it as an empty stub with the same revision id if it was already applied everywhere, or repoint the child's downrevision at the real parent if it was never applied. Verify with alembic history before running anything.
The query
alembic error: Can't locate revision identified by 'a1b2c3d4' after deleting a migration fileUse this when
- alembic fails with "Can't locate revision identified by"
- A migration file was deleted but something still references it
- alembic history, heads, or upgrade all error on the missing id
- An agent deleted a file and broke the revision chain
Not for
- Multiple heads present (that is a merge problem, not a missing file)
- A database that is simply behind head (run upgrade head)
- Revision ids that never existed anywhere (check for typos in hand-written ids)
Steps
1. Find which file references the missing id
grep -rn "a1b2c3d4" [migrations dir]/versions/Expected output: one or more files whose down_revision mentions a1b2c3d4. Those are the children of the deleted revision; they are what break every alembic command.
2. Check whether the deleted revision ever applied anywhere
SELECT version_num FROM alembic_version;And check version control for the deleted file:
git log --diff-filter=D -- [migrations dir]/versions/Expected output: the current version plus the deleted file's name and its original content. If the revision id appears in any environment's alembic_version (prod, staging), it applied and you must preserve the id. If it never applied anywhere, you can simply repoint.
3. Case A: it applied somewhere - restore the file
git checkout [commit before deletion] -- [migrations dir]/versions/[deleted file].pyExpected output: the file is back with its original revision id intact. Every environment's history stays consistent because the id the database recorded still resolves to a file.
4. Case B: it applied everywhere and the file is unrecoverable - recreate a stub
Create a new revision file with the same revision id and empty upgrade/downgrade bodies, chained between the same parent and children the original had. The id is what matters, not the content, because the work is already recorded as done.
Expected output: alembic resolves the chain again. The stub is a permanent placeholder: leave a comment in it explaining why it exists.
5. Case C: it never applied anywhere - repoint the child
Edit the child file found in step 1 and change its down_revision from the deleted id to the deleted revision's own parent (read from version control). Then delete any other trace of the missing id.
Expected output: the chain skips the never-applied revision cleanly, with no stub needed.
6. Verify the chain is whole again
alembic historyExpected output: the full revision list prints with no "Can't locate revision" error, and alembic heads shows the expected head or heads. Only then run upgrade.
Tool compatibility
alembic 1.x, any database backend. The revision-file mechanics are identical across backends.
Variant phrasings
alembic revision not found after deleting migration file
Steps 1 through 3: restore from version control is almost always the right fix when the revision applied anywhere.
alembic down_revision references missing revision
Step 5: if nothing ever applied it, repointing the child is cleaner than a stub.
Can't locate revision identified by [id] alembic
Step 1 first: the id in the error is the child's missing parent, not necessarily the file you deleted. Grep to find who references it.
Why it happens
Alembic builds the revision graph from files on disk, following down_revision links. Deleting a file removes a graph node while its children still point at it, so graph traversal fails before any database work happens. The database is untouched; only the file graph is broken.
Edge cases
- If production's alembic_version holds the deleted id, every fix must keep that id resolvable: restore or stub, never repoint.
- A merge revision (downrevision as a tuple) can hide the reference: grep the raw id, not just downrevision lines.
- After fixing, run alembic check on a fresh database to prove new environments can bootstrap from scratch.
- Agents: never delete a migration file that has already applied anywhere. Treat applied files as immutable.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_87Vrt5F2TAXtwaBp8wUAaw