sqlalchemy/alembic · error · RevisionError

Walked too far

Error message

Walked too far

What it means

Raised by _parse_downgrade_target when a relative downgrade with an explicit symbol ('symbol+n') walked past the end of the line and produced no revision. The requested number of forward steps from that symbol exceeds available migrations. It is a RevisionError.

Source

Thrown at alembic/script/revision.py:1128

        if match:
            branch_label, symbol, relative = match.groups()
            rel_int = int(relative)
            if rel_int >= 0:
                if symbol is None:
                    # Downgrading to current + n is not valid.
                    raise RevisionError(
                        "Relative revision %s didn't "
                        "produce %d migrations" % (relative, abs(rel_int))
                    )
                # Find target revision relative to given symbol.
                rev = self._walk(
                    symbol,
                    rel_int,
                    branch_label,
                    no_overwalk=assert_relative_length,
                )
                if rev is None:
                    raise RevisionError("Walked too far")
                return branch_label, rev
            else:
                relative_revision = symbol is None
                if relative_revision:
                    # Find target revision relative to current state.
                    if branch_label:
                        cr_tuple = util.to_tuple(current_revisions)
                        symbol_list: Sequence[str]
                        symbol_list = self.filter_for_lineage(
                            cr_tuple, branch_label
                        )
                        if not symbol_list:
                            # check the case where there are multiple branches
                            # but there is currently a single heads, since all
                            # other branch heads are dependent of the current
                            # single heads.
                            all_current = cast(
                                set[Revision], self._get_all_current(cr_tuple)

View on GitHub (pinned to 44fb345033)

Solutions

  1. Reduce the step count or use the symbolic 'head' as the target.
  2. Verify available migrations above the symbol with 'alembic history'.
  3. Pass the explicit destination revision id.

Example fix

# before
alembic downgrade deadbeef+10   # fewer than 10 above
# after
alembic downgrade deadbeef+2    # or 'alembic downgrade head'
Defensive patterns

Strategy: validation

Validate before calling

# count available migrations above the symbol
rev = script.get_revision(symbol)
above = list(script._revision_map._get_descendant_nodes([rev]))
if int(steps) > len(above):
    raise ValueError('only %d migrations above %s' % (len(above), symbol))

Try / catch

from alembic.script.revision import RevisionError
try:
    command.downgrade(cfg, '%s+%s' % (symbol, steps))
except RevisionError as e:
    if 'Walked too far' in str(e):
        command.downgrade(cfg, 'head')  # cap at head

Prevention

When it happens

Trigger: Issuing something like 'alembic downgrade <revid>+5' where fewer than 5 forward migrations exist from revid; walking past head while assert_relative_length is on.

Common situations: Overestimating how many migrations exist above a given revision; stale assumptions after migrations were removed.

Related errors


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