sqlalchemy/alembic · error · ValueError
This MigrationScript instance has a multiple-entry list for
Error message
This MigrationScript instance has a multiple-entry list for DowngradeOps; please use the downgrade_ops_list attribute.
What it means
Raised by the MigrationScript.downgrade_ops property when more than one DowngradeOps entry exists in _downgrade_ops. Mirrors the upgrade case: once multiple downgrade streams exist, the scalar property is disabled and you must use downgrade_ops_list.
Source
Thrown at alembic/operations/ops.py:2856
else:
return self._upgrade_ops[0]
@upgrade_ops.setter
def upgrade_ops(self, upgrade_ops: UpgradeOps | list[UpgradeOps]) -> None:
self._upgrade_ops = util.to_list(upgrade_ops)
for elem in self._upgrade_ops:
assert isinstance(elem, UpgradeOps)
@property
def downgrade_ops(self) -> DowngradeOps | None:
"""An instance of :class:`.DowngradeOps`.
.. seealso::
:attr:`.MigrationScript.downgrade_ops_list`
"""
if len(self._downgrade_ops) > 1:
raise ValueError(
"This MigrationScript instance has a multiple-entry "
"list for DowngradeOps; please use the "
"downgrade_ops_list attribute."
)
elif not self._downgrade_ops:
return None
else:
return self._downgrade_ops[0]
@downgrade_ops.setter
def downgrade_ops(
self, downgrade_ops: DowngradeOps | list[DowngradeOps]
) -> None:
self._downgrade_ops = util.to_list(downgrade_ops)
for elem in self._downgrade_ops:
assert isinstance(elem, DowngradeOps)
@propertyView on GitHub (pinned to 44fb345033)
Solutions
- Use script.downgrade_ops_list and iterate over all entries.
- Ensure only one DowngradeOps is stored if the scalar accessor is required.
- Branch rendering logic on len(downgrade_ops_list) > 1.
Example fix
// before
ops = script.downgrade_ops # raises ValueError when multiple
// after
for ops in script.downgrade_ops_list:
... Defensive patterns
Strategy: type-guard
Validate before calling
def get_downgrade_ops(script):
n = len(script.downgrade_ops_list)
if n > 1:
return script.downgrade_ops_list
return script.downgrade_ops_list[0] if n == 1 else None Type guard
def has_multiple_downgrade_ops(script) -> bool:
return len(script.downgrade_ops_list) > 1 Try / catch
try:
ops = script.downgrade_ops
except ValueError:
ops = script.downgrade_ops_list Prevention
- Prefer downgrade_ops_list in generic/render code.
- Branch on len(downgrade_ops_list) in autogenerate hooks.
- Keep scalar access to the single-entry case.
When it happens
Trigger: Accessing script.downgrade_ops on a MigrationScript populated with a list of multiple DowngradeOps; custom process_revision_directives that produce several downgrade passes corresponding to multiple upgrade passes.
Common situations: Custom autogenerate hooks splitting downgrades into multiple DowngradeOps; template/render code reading the scalar property on a multi-pass script.
Related errors
- This MigrationScript instance has a multiple-entry list for
- constraint cannot be produced; original constraint is not pr
- operation is not reversible; original column is not present
- 'type' can be one of %s
- Can't drop table in batch mode
AI-assisted analysis of sqlalchemy/alembic@44fb345033 (2026-08-04).
Data as JSON: /data/errors/86830460d40dc14f.json.
Report an issue: GitHub.