MP060critical

alter-type-rename-value

ALTER TYPE RENAME VALUE is not replicated via logical replication, causing enum mismatches on subscribers.

operation
Enums
lock taken
no table lock
remediation
Manual rewrite
category
Data safety

What triggers it

ALTER TYPE ... RENAME VALUE on an AlterEnumStmt node, detected by checking that the statement's lowercased original SQL text contains the literal phrase rename value — the AST shape for rename versus add differs across libpg-query versions, so the rule leans on the text match instead.

What does not

Any other AlterEnumStmt form, most notably ADD VALUE, whose SQL text doesn't contain rename value. Since detection is entirely text-based, nothing else about the statement is inspected once that phrase is absent.

Where it applies

Applies to every PostgreSQL version MigrationPilot targets. It works on the SQL text alone — no database connection needed.

The lock, and what it blocks

No lock is named in the source — the danger isn't blocking, it's that RENAME VALUE edits the pg_enum catalog entry in place, and logical replication never ships catalog changes to subscribers at all.

Why it matters

RENAME VALUE modifies the pg_enum catalog entry in-place. Logical replication does not replicate catalog changes. Subscribers retain the old value name, causing decode failures on replicated rows.

Unsafe, and safe

Flagged

ALTER TYPE status RENAME VALUE 'active' TO 'enabled';
-- Subscribers still have 'active', not 'enabled'

Safe alternative

-- Add new value, migrate data:
ALTER TYPE status ADD VALUE 'enabled';
UPDATE events SET status = 'enabled' WHERE status = 'active';

What it assumes

The rule assumes a subscriber exists that cares about the old value name — a read replica, a CDC pipeline, a branched database. On a database with no logical replication downstream, a rename is harmless. It also can't tell whether any row actually uses the renamed value, so it fires even on a value nothing currently references.

What backs this rule

Every rule is a claim about PostgreSQL, so it carries what the claim rests on: a handbook chapter that cites the manual, the incidents that put it there, and the version it was last checked against.

Adding a value to an enum is the smallest schema change there is, and it breaks more migration frameworks than anything else in this handbook — because almost every framework wraps migrations in a transaction by default, and this statement has rules about transactions.

verified against
PostgreSQL 17.10
last checked
2026-08-11
confidence
High

What the CLI prints

migrationpilot analyze migration.sql
✗ [MP060] CRITICAL (line 1)
  ALTER TYPE "status" RENAME VALUE is not replicated via logical replication. This silently causes enum mismatches on subscribers (Neon, Supabase, RDS replicas, CDC pipelines).

  Safe alternative:
  -- Instead of RENAME VALUE, use add-migrate-drop:
  -- 1. ALTER TYPE status ADD VALUE 'new_name';
  -- 2. UPDATE table SET col = 'new_name' WHERE col = 'old_name';
  -- 3. -- Drop old value requires recreating the type (complex but safe)

  Why: RENAME VALUE modifies the pg_enum catalog entry in-place. Logical replication does not replicate catalog changes, so subscribers (Neon branches, Supabase read replicas, RDS logical replicas, Debezium CDC) retain the old value name. Any row containing the renamed value that arrives via replication will fail to decode. The only safe alternative is to add a new value, migrate data, then drop the old one.
  Docs: https://migrationpilot.dev/rules/mp060

Generated by running the CLI's own formatter over the flagged example above, so it is the text the tool actually produces. A real run also reports the other rules that fire on the same statement; those blocks are left out here.

Turning it off

For one statement, put a comment on the line before it:

-- migrationpilot-disable MP060
ALTER TYPE status RENAME VALUE 'active' TO 'enabled';

For the whole project, in .migrationpilotrc.yml — by name or by id:

.migrationpilotrc.yml
rules:
  MP060: false

# or keep it, and downgrade it
rules:
  MP060:
    severity: warning

Try it

Open this rule's flagged example in the playground. It runs in your browser — edit it and watch the finding appear and disappear.

Run MP060 in the playground

Related rules