All rules Rule BV006
critical
free in the CLI

Non-transactional statement mixed into a multi-statement migration

Critical — this fails outright or takes production down.

What it catches

Statements like CREATE INDEX CONCURRENTLY refuse to run in a transaction block. Mixed with other DDL in one migration, either the whole file fails, or the runner drops the transaction and a mid-file error strands the schema between states with no rollback.

Fires on

ALTER TABLE orders ADD COLUMN region text;
CREATE INDEX CONCURRENTLY idx ON orders (region);

Do this instead

Split the file: transactional DDL in one migration, and each CREATE INDEX CONCURRENTLY (or other non-transactional statement) alone in its own migration marked to run outside a transaction, so every step either fully commits or fully rolls back.

-- migration 1 (transactional):
SET lock_timeout = '5s';
ALTER TABLE orders ADD COLUMN region text;
-- migration 2 (alone, outside a transaction):
--    CREATE INDEX CONCURRENTLY idx_orders_region ON orders (region);
Catch this before it ships

This rule runs locally in the free CLI — or with the full corpus through the hosted service: npx bolvrk check migration.sql