sqlalchemy/alembic · error · ResolutionError

Revision %s is not a member of branch '%s'

Error message

Revision %s is not a member of branch '%s'

What it means

Raised by _revision_for_ident when a check_branch is supplied and the resolved revision does not share lineage with that branch (per _shares_lineage). In other words, 'label@revid' was given but revid is not on the branch named by label. It is a ResolutionError.

Source

Thrown at alembic/script/revision.py:659

                    resolved_id,
                )
            elif len(revs) > 1:
                raise ResolutionError(
                    "Multiple revisions start "
                    "with '%s': %s..."
                    % (resolved_id, ", ".join("'%s'" % r for r in revs[0:3])),
                    resolved_id,
                )
            else:
                revision = self._revision_map[revs[0]]

        if check_branch and revision is not None:
            assert branch_rev is not None
            assert resolved_id
            if not self._shares_lineage(
                revision.revision, branch_rev.revision
            ):
                raise ResolutionError(
                    "Revision %s is not a member of branch '%s'"
                    % (revision.revision, check_branch),
                    resolved_id,
                )
        return revision

    def _filter_into_branch_heads(
        self, targets: Iterable[_RevisionOrBase | None]
    ) -> set[_RevisionOrBase | None]:
        targets = set(targets)

        for rev in list(targets):
            assert rev
            if targets.intersection(
                self._get_descendant_nodes([rev], include_dependencies=False)
            ).difference([rev]):
                targets.discard(rev)
        return targets

View on GitHub (pinned to 44fb345033)

Solutions

  1. Drop the branch scope and reference the revision directly if you just want that revision.
  2. Verify the revision is actually on the intended branch by checking its branch_labels and ancestors.
  3. Re-apply the correct branch_labels in the migration file if it was mislabeled.

Example fix

# before
alembic downgrade featurex@deadbeef  # not a member of featurex
# after
alembic downgrade deadbeef           # absolute, no branch scope
Defensive patterns

Strategy: validation

Validate before calling

rev = script.get_revision(rev_id)
branch_rev = script.get_revision('%s@head' % branch_label)
if not script._revision_map._shares_lineage(rev, [branch_rev]):
    raise ValueError('%s is not on branch %s' % (rev_id, branch_label))

Try / catch

from alembic.script.revision import ResolutionError
try:
    rev = script.get_revision('%s@%s' % (branch_label, rev_id))
except ResolutionError as e:
    # not a member of branch; drop the scope
    rev = script.get_revision(rev_id)

Prevention

When it happens

Trigger: Issuing 'branch_a@<revid>' where revid lives on a different branch; cross-branch references in downgrade/upgrade commands; mislabeling a migration with the wrong branch_labels.

Common situations: Migrations that were moved between branches during a rebase; copy-paste of a revision id from one branch into a command scoped to another.

Related errors


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