sqlalchemy/alembic · error · MultipleHeads

Multiple heads are present for given argument '%s'; %s

Error message

Multiple heads are present for given argument '%s'; %s

What it means

Raised by get_current_head(branch_label) when more than one head revision exists for the requested scope (the whole tree, or a branch_label). get_current_head is only valid when there is exactly one head; the docstring explicitly directs callers to ScriptDirectory.get_heads() when branching is possible. It is a MultipleHeads exception (subclass of RevisionError).

Source

Thrown at alembic/script/revision.py:501

        preferred.

        :param branch_label: optional branch name which will limit the
         heads considered to those which include that branch_label.

        :return: a string revision number.

        .. seealso::

            :meth:`.ScriptDirectory.get_heads`

        """
        current_heads: Sequence[str] = self.heads
        if branch_label:
            current_heads = self.filter_for_lineage(
                current_heads, branch_label
            )
        if len(current_heads) > 1:
            raise MultipleHeads(
                current_heads,
                "%s@head" % branch_label if branch_label else "head",
            )

        if current_heads:
            return current_heads[0]
        else:
            return None

    def _get_base_revisions(self, identifier: str) -> tuple[str, ...]:
        return self.filter_for_lineage(self.bases, identifier)

    def get_revisions(
        self, id_: _GetRevArg | None
    ) -> tuple[_RevisionOrBase | None, ...]:
        """Return the :class:`.Revision` instances with the given rev id
        or identifiers.

View on GitHub (pinned to 44fb345033)

Solutions

  1. Run 'alembic heads' to list all heads, then 'alembic merge -m "merge heads" <head1> <head2>' to create a merge revision.
  2. Use get_heads() (plural) in code instead of get_current_head() to handle branching explicitly.
  3. Specify an explicit target revision id instead of the symbolic 'head' when upgrading.

Example fix

// before
head = script.get_current_head()  # MultipleHeads
// after
heads = script.get_heads()
if len(heads) == 1:
    head = heads[0]
else:
    # merge or pick an explicit target
    raise SystemExit("multiple heads: %s" % heads)
Defensive patterns

Strategy: try-catch

Validate before calling

from alembic.script.revision import MultipleHeads
heads = script.get_heads()
if len(heads) > 1:
    # merge or disambiguate before calling get_current_head
    ...

Try / catch

from alembic.script.revision import MultipleHeads
try:
    head = script.get_current_head(branch)
except MultipleHeads as e:
    # e.heads lists the heads; merge or pick one explicitly
    head = e.heads[0]  # or run alembic.merge

Prevention

When it happens

Trigger: Calling get_current_head() (no args) on a script directory that has diverged into multiple heads, or get_current_head('mybranch') where that branch lineage still has more than one head. Common via 'alembic upgrade head' or programmatic command.runs() when the repo has unresolved branches.

Common situations: Two developers added migrations off the same parent and merged them, creating two heads; a feature-branch migration with branch_labels that was never merged; CI running 'alembic upgrade head' on a multi-head tree.

Related errors


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