{"id":"d5ea6d34176db533","repo":"sqlalchemy/alembic","slug":"multiple-revisions-start-with-s-s","errorCode":null,"errorMessage":"Multiple revisions start with '%s': %s...","messagePattern":"Multiple revisions start with '(.+?)': (.+?)\\.\\.\\.","errorType":"exception","errorClass":"ResolutionError","httpStatus":null,"severity":"error","filePath":"alembic/script/revision.py","lineNumber":644,"sourceCode":"\n            if branch_rev:\n                revs = self.filter_for_lineage(revs, check_branch)\n            if not revs:\n                raise ResolutionError(\n                    \"No such revision or branch '%s'%s\"\n                    % (\n                        resolved_id,\n                        (\n                            \"; please ensure at least four characters are \"\n                            \"present for partial revision identifier matches\"\n                            if len(resolved_id) < 4\n                            else \"\"\n                        ),\n                    ),\n                    resolved_id,\n                )\n            elif len(revs) > 1:\n                raise ResolutionError(\n                    \"Multiple revisions start \"\n                    \"with '%s': %s...\"\n                    % (resolved_id, \", \".join(\"'%s'\" % r for r in revs[0:3])),\n                    resolved_id,\n                )\n            else:\n                revision = self._revision_map[revs[0]]\n\n        if check_branch and revision is not None:\n            assert branch_rev is not None\n            assert resolved_id\n            if not self._shares_lineage(\n                revision.revision, branch_rev.revision\n            ):\n                raise ResolutionError(\n                    \"Revision %s is not a member of branch '%s'\"\n                    % (revision.revision, check_branch),\n                    resolved_id,","sourceCodeStart":626,"sourceCodeEnd":662,"githubUrl":"https://github.com/sqlalchemy/alembic/blob/44fb3450330204b222ff05135e1fbbbdb28c44db/alembic/script/revision.py#L626-L662","documentation":"Raised by _revision_for_ident when a partial identifier (>= 4 characters) matches more than one revision, making the target ambiguous. The message lists the first three matching ids. It is a ResolutionError.","triggerScenarios":"Passing a prefix like 'abc1' that two or more revision ids share (revision ids are random but collisions on a short prefix are possible); committing migrations whose ids share a common stem.","commonSituations":"Short revision-id prefixes in automation scripts; tooling that truncates ids for display and then feeds the truncated form back into commands.","solutions":["Provide more characters of the revision id until it is unique (ideally the full id).","Use the symbolic 'head'/'base' or a branch label if appropriate.","Regenerate colliding revision ids with 'alembic revision' if the collision is on a real prefix."],"exampleFix":"# before\nalembic upgrade abcd   # matches abcd111..., abcd222...\n# after\nalembic upgrade abcd111abcdef","handlingStrategy":"validation","validationCode":"matches = [\n    rid for rid in {r.revision for r in script.walk_revisions()}\n    if rid.startswith(prefix)\n]\nif len(matches) > 1:\n    raise ValueError('ambiguous prefix %s: %s' % (prefix, matches))","typeGuard":null,"tryCatchPattern":"from alembic.script.revision import ResolutionError\ntry:\n    rev = script.get_revision(prefix)\nexcept ResolutionError as e:\n    if 'Multiple revisions' in str(e):\n        # lengthen the prefix until unique\n        ...","preventionTips":["Use full revision ids whenever possible.","Never hardcode short prefixes in scripts.","Check uniqueness of a prefix before using it."],"tags":["revision-resolution","partial-id","ambiguous","alembic"],"analyzedSha":"44fb3450330204b222ff05135e1fbbbdb28c44db","analyzedAt":"2026-08-04T19:57:10.248Z","schemaVersion":2}