sqlalchemy/alembic · error · ResolutionError

No such branch: '%s'

Error message

No such branch: '%s'

What it means

Raised by _resolve_branch(branch_label) when the label is neither a registered branch label in the revision map nor resolvable as an ordinary revision. This is the underlying error behind 'branch@...' syntax that names a nonexistent branch. It is a ResolutionError.

Source

Thrown at alembic/script/revision.py:591

        full revision.

        """

        resolved_id, branch_label = self._resolve_revision_number(id_)
        if len(resolved_id) > 1:
            raise MultipleHeads(resolved_id, id_)

        resolved: str | tuple[()] = resolved_id[0] if resolved_id else ()
        return self._revision_for_ident(resolved, branch_label)

    def _resolve_branch(self, branch_label: str) -> Revision | None:
        try:
            branch_rev = self._revision_map[branch_label]
        except KeyError:
            try:
                nonbranch_rev = self._revision_for_ident(branch_label)
            except ResolutionError as re:
                raise ResolutionError(
                    "No such branch: '%s'" % branch_label, branch_label
                ) from re

            else:
                return nonbranch_rev
        else:
            return branch_rev

    def _revision_for_ident(
        self,
        resolved_id: str | tuple[()] | None,
        check_branch: str | None = None,
    ) -> Revision | None:
        branch_rev: Revision | None
        if check_branch:
            branch_rev = self._resolve_branch(check_branch)
        else:
            branch_rev = None

View on GitHub (pinned to 44fb345033)

Solutions

  1. List known branches: inspect the migration scripts for branch_labels assignments, or enumerate script.get_revisions('heads') and read .branch_labels.
  2. Correct the label spelling or drop the 'branch@' prefix if you meant a plain revision.
  3. If the branch migration was deleted, restore it or re-add the branch_labels to the appropriate revision.

Example fix

# before
alembic upgrade typobranch@head   # No such branch
# after
alembic upgrade correctbranch@head
Defensive patterns

Strategy: validation

Validate before calling

known_labels = {
    lbl
    for r in script.walk_revisions()
    for lbl in r.branch_labels
}
if branch_label not in known_labels:
    raise ValueError('unknown branch label: %s' % branch_label)

Try / catch

from alembic.script.revision import ResolutionError
try:
    script.get_revision('%s@head' % branch_label)
except ResolutionError as e:
    # handle unknown branch
    ...

Prevention

When it happens

Trigger: Issuing 'alembic upgrade nonexistentbranch@head', 'alembic downgrade mybranch@-1', or any API call passing a 'label@rev' string where label was never declared via branch_labels in a migration.

Common situations: Typo in a branch label; referencing a branch label that was removed when its migration was deleted; team members who don't have the branch-labeled migration checked out.

Related errors


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