sqlalchemy/alembic · error · RevisionError

Ambiguous upgrade from multiple current revisions

Error message

Ambiguous upgrade from multiple current revisions

What it means

Raised by _parse_upgrade_target for a relative upgrade ('+n', no explicit symbol) when the current revisions resolve to more than one starting point that cannot be disambiguated by a branch label. Relative upgrades require a single unambiguous starting revision; multiple current heads make 'current + n' undefined. It is a RevisionError.

Source

Thrown at alembic/script/revision.py:1269

                            ),
                            branch_label,
                        )
                        # Find the tips of this set of revisions (revisions
                        # without children within the set).
                        start_revs = tuple(
                            {rev.revision for rev in active_on_branch}
                            - {
                                down
                                for rev in active_on_branch
                                for down in rev._normalized_down_revisions
                            }
                        )
                        if not start_revs:
                            # We must need to go right back to base to find
                            # a starting point for this branch.
                            start_revs = (None,)
                if len(start_revs) > 1:
                    raise RevisionError(
                        "Ambiguous upgrade from multiple current revisions"
                    )
                # Walk up from unique target revision.
                rev = self._walk(
                    start=start_revs[0],
                    steps=relative,
                    branch_label=branch_label,
                    no_overwalk=assert_relative_length,
                )
                if rev is None:
                    raise RevisionError(
                        "Relative revision %s didn't "
                        "produce %d migrations" % (relative_str, abs(relative))
                    )
                return (rev,)
            else:
                # Walk is relative to a given revision, not the current state.
                return (

View on GitHub (pinned to 44fb345033)

Solutions

  1. Merge the heads with 'alembic merge' so the database has a single head.
  2. Scope the upgrade with a branch label: 'alembic upgrade mybranch@+2'.
  3. Upgrade to an absolute target revision instead of a relative offset.

Example fix

# before
alembic upgrade +2   # multiple current heads -> ambiguous
# after
alembic upgrade mybranch@+2   # or merge heads first
Defensive patterns

Strategy: validation

Validate before calling

with engine.begin() as conn:
    ctx = MigrationContext.configure(conn)
    current = ctx.get_current_revisions()  # tuple
if len(set(current)) > 1:
    raise ValueError(
        'relative upgrade ambiguous from heads: %s; scope a branch' % (current,)
    )

Try / catch

from alembic.script.revision import RevisionError
try:
    command.upgrade(cfg, '+%d' % steps)
except RevisionError as e:
    if 'Ambiguous upgrade' in str(e):
        command.upgrade(cfg, '%s@+%d' % (branch, steps))  # scope a branch

Prevention

When it happens

Trigger: Running 'alembic upgrade +2' on a database stamped with multiple heads (multi-branch tree) without specifying a branch.

Common situations: Multi-head database state (e.g., after merging branches at the script level but the DB still holds several heads); relative upgrades in CI against a branched tree.

Related errors


AI-assisted analysis of sqlalchemy/alembic@44fb345033 (2026-08-04). Data as JSON: /data/errors/bd7f0fbcad63fbdc.json. Report an issue: GitHub.