sqlalchemy/alembic · error · RevisionError

Branch name '%s' in revision %s already used by revision %s

Error message

Branch name '%s' in revision %s already used by revision %s

What it means

Raised as RevisionError in _map_branch_labels() when a branch_label declared on a revision collides with a name already present in the revision map (i.e. another revision id or an already-mapped branch label). Branch labels are used to address revision branches and must be unique identifiers within the revision namespace; a collision makes branch addressing ambiguous.

Source

Thrown at alembic/script/revision.py:324

                _real_bases,
                map_=cast(_RevisionMapType, rev_map),
            )
        )
        deleted_revs = set(rev_map.keys()) - total_space
        if deleted_revs:
            raise DependencyCycleDetected(sorted(deleted_revs))

    def _map_branch_labels(
        self, revisions: Collection[Revision], map_: _RevisionMapType
    ) -> None:
        for revision in revisions:
            if revision.branch_labels:
                assert revision._orig_branch_labels is not None
                for branch_label in revision._orig_branch_labels:
                    if branch_label in map_:
                        map_rev = map_[branch_label]
                        assert map_rev is not None
                        raise RevisionError(
                            "Branch name '%s' in revision %s already "
                            "used by revision %s"
                            % (
                                branch_label,
                                revision.revision,
                                map_rev.revision,
                            )
                        )
                    map_[branch_label] = revision

    def _add_branches(
        self, revisions: Collection[Revision], map_: _RevisionMapType
    ) -> None:
        for revision in revisions:
            if revision.branch_labels:
                revision.branch_labels.update(revision.branch_labels)
                for node in self._get_descendant_nodes(
                    [revision], map_, include_dependencies=False

View on GitHub (pinned to 44fb345033)

Solutions

  1. Give each branch a unique branch_label distinct from all revision ids and other labels.
  2. Remove the duplicate branch_label from one of the conflicting revisions.
  3. Re-create the revision with 'alembic revision --branch-label <unique_name>'.

Example fix

// before
# revision aaa branch_labels=('feature',)
# revision bbb branch_labels=('feature',)  # collision -> RevisionError

// after
# revision bbb branch_labels=('feature2',)
Defensive patterns

Strategy: validation

Validate before calling

def branch_labels_unique(revisions):
    seen = {}
    for rev in revisions:
        for label in (getattr(rev, 'branch_labels', None) or ()):
            if label in seen:
                return False, (label, seen[label], rev.revision)
            seen[label] = rev.revision
    return True, None

Try / catch

try:
    script_dir.get_revision(branch_label)
except Exception as e:
    if 'already used by revision' in str(e):
        # rename/remove the duplicate branch_label on the conflicting revision
        ...
    else:
        raise

Prevention

When it happens

Trigger: Two revisions both declaring the same branch_label; a branch_label that equals an existing revision identifier; declaring a branch_label on a revision that another revision already claimed as its branch_label.

Common situations: Setting identical branch_labels on parallel branches; naming a branch label the same as a revision hash; copy-pasting a revision file and forgetting to change the branch_label; using --branch-label with a name that's already taken.

Related errors


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