All rules Rule BP004
note
tier 2 — needs a live schema
hosted, paid — --remote

DROP INDEX removes the only index covering a foreign key

Note — this works and blocks nothing, but a performance regression is likely.

What it catches

Postgres never indexes the referencing side of a foreign key itself; the index someone added later is what keeps parent-side UPDATE and DELETE cheap. Drop it and every change to the referenced table sequential-scans the child table to enforce the constraint — the same regression BV017 warns about, arriving through the back door.

Fires on

DROP INDEX CONCURRENTLY idx_orders_user;

Do this instead

Keep a covering index whose leading columns match the foreign key — replace before you remove (create the new index CONCURRENTLY first, then drop the old one), or drop the constraint too if the relationship is going away. Both keep this rule silent.

-- Replace first (own migration, outside a transaction):
CREATE INDEX CONCURRENTLY idx_orders_user_created ON orders (user_id, created_at);
-- Next migration: DROP INDEX CONCURRENTLY idx_orders_user;
Catch this before it ships

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