{"record":{"id":"86830460d40dc14f","repo":"sqlalchemy/alembic","slug":"this-migrationscript-instance-has-a-multiple-entry-868304","errorCode":null,"errorMessage":"This MigrationScript instance has a multiple-entry list for DowngradeOps; please use the downgrade_ops_list attribute.","messagePattern":"This MigrationScript instance has a multiple-entry list for DowngradeOps; please use the downgrade_ops_list attribute\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"alembic/operations/ops.py","lineNumber":2856,"sourceCode":"        else:\n            return self._upgrade_ops[0]\n\n    @upgrade_ops.setter\n    def upgrade_ops(self, upgrade_ops: UpgradeOps | list[UpgradeOps]) -> None:\n        self._upgrade_ops = util.to_list(upgrade_ops)\n        for elem in self._upgrade_ops:\n            assert isinstance(elem, UpgradeOps)\n\n    @property\n    def downgrade_ops(self) -> DowngradeOps | None:\n        \"\"\"An instance of :class:`.DowngradeOps`.\n\n        .. seealso::\n\n            :attr:`.MigrationScript.downgrade_ops_list`\n        \"\"\"\n        if len(self._downgrade_ops) > 1:\n            raise ValueError(\n                \"This MigrationScript instance has a multiple-entry \"\n                \"list for DowngradeOps; please use the \"\n                \"downgrade_ops_list attribute.\"\n            )\n        elif not self._downgrade_ops:\n            return None\n        else:\n            return self._downgrade_ops[0]\n\n    @downgrade_ops.setter\n    def downgrade_ops(\n        self, downgrade_ops: DowngradeOps | list[DowngradeOps]\n    ) -> None:\n        self._downgrade_ops = util.to_list(downgrade_ops)\n        for elem in self._downgrade_ops:\n            assert isinstance(elem, DowngradeOps)\n\n    @property","sourceCodeStart":2838,"sourceCodeEnd":2874,"githubUrl":"https://github.com/sqlalchemy/alembic/blob/5551b5d35f985c99cb8f1af2b3c526b050e4c059/alembic/operations/ops.py#L2838-L2874","documentation":"Raised as ValueError by the MigrationScript.downgrade_ops getter (ops.py:2847-2859) when self._downgrade_ops has more than one entry. The exact mirror of the upgrade_ops (errorIndex 28) check: in multidb autogenerate, multiple DowngradeOps are stored and the singular accessor is intentionally disabled, pointing to downgrade_ops_list.","triggerScenarios":"Accessing migration_script.downgrade_ops on a multi-database MigrationScript where >1 DowngradeOps were generated. Typically inside a process_revision_directives hook or custom renderer that assumes a single downgrade op.","commonSituations":"Multidb template migrations; refactoring a single-DB hook to run against a multi-DB project; assuming the script has one downgrade when env.py iterates engines.","solutions":["Use migration_script.downgrade_ops_list and iterate it.","In custom hooks, write `for do in script.downgrade_ops_list: ...` instead of `script.downgrade_ops`.","Confirm your env.py matches the single-DB pattern if you truly expect one DowngradeOps."],"exampleFix":"// before\nscript = directives[0]\ndown = script.downgrade_ops  # raises in multidb\n// after\nscript = directives[0]\nfor down in script.downgrade_ops_list:\n    ...  # handle each DB's downgrade","handlingStrategy":"validation","validationCode":"# In process_revision_directives, always iterate the downgrade list.\ndef process_revision_directives(context, revision, directives):\n    script = directives[0]\n    for down_ops in script.downgrade_ops_list:  # never script.downgrade_ops\n        ...","typeGuard":"from alembic.operations.ops import MigrationScript\n\ndef is_multidb(script: MigrationScript) -> bool:\n    return len(script._downgrade_ops) > 1","tryCatchPattern":"try:\n    down = script.downgrade_ops\nexcept ValueError:\n    down = None\nops_list = script.downgrade_ops_list  # always safe","preventionTips":["Use script.downgrade_ops_list in custom hooks; it works for single- and multi-DB.","Check len(script._downgrade_ops) before the singular accessor.","Treat any migration script as potentially multi-DB in generic tooling."],"tags":["alembic","autogenerate","multidb","operations-api"],"backgroundTag":null,"analyzedSha":"5551b5d35f985c99cb8f1af2b3c526b050e4c059","analyzedAt":"2026-08-11T01:38:46.612Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}