Check
¶ Count the heads
cd apps/api
alembic heads
Expected
$ alembic heads one head Exactly one line. Safe to promote.Multiple heads
$ alembic heads head a head b More than one line. Fix before promoting.Deployment & release
Run this before every promotion. Two branches that each add a migration off the same parent leave two heads, and alembic upgrade head refuses to run. Fix it on development, before anything reaches main.
Check
cd apps/api
alembic heads
Expected
$ alembic heads one head Exactly one line. Safe to promote.Multiple heads
$ alembic heads head a head b More than one line. Fix before promoting.Fix · only if multiple heads exist
alembic merge heads -m "merge <a> and <b>"
alembic upgrade head
alembic heads
alembic merge headsCreates a merge revision that joins the two heads.
alembic upgrade headApplies it locally.
alembic headsMust print exactly one line again.
Timing matters
development before merging to mainAlready fixed it on main? Force both components with gh workflow run deploy-do.yml --ref main -f api=true -f connector=true. The full sequence and why it happens are in Deployment workflow → failure modes.
Prevention
Renumber the later migration, update its down_revision, and update the head test so a single head is restored.
Use ALTER TABLE ... ADD COLUMN IF NOT EXISTS plus a constant server_default so rows fill without a full table rewrite. This tolerates staged rollouts.
Add a named CHECK constraint, and verify upgrade and downgrade locally before deploying.