Enum value added inside a multi-statement migration
Warning — this works, but blocks traffic or rewrites data at scale.
What it catches
Adding an enum value has transaction restrictions: before Postgres 12 it errors inside a transaction block, and on 12+ the new value is unusable until the transaction commits. A migration runner that wraps the file in one transaction either fails outright or fails on the first statement that uses the new value.
Fires on
ALTER TYPE order_status ADD VALUE 'archived';
UPDATE orders SET status = 'archived';Do this instead
Put ALTER TYPE ... ADD VALUE alone in its own migration so it commits before anything uses the value; statements that use the new value go in a later migration. On Postgres 12+ the statement is allowed inside a transaction, but the value stays unusable until that transaction commits — the split fixes both eras.
-- migration 1 (single statement, commits on its own):
ALTER TYPE order_status ADD VALUE IF NOT EXISTS 'archived';
-- migration 2 (later): statements that USE 'archived' This rule runs in the hosted service on Startup and above — add --remote with a team token, or use the GitHub Action: npx bolvrk check migration.sql