sqlalchemy/alembic · error · TypeError
Can't send params and multiparams at the same time
Error message
Can't send params and multiparams at the same time
What it means
DefaultImpl._exec raises TypeError when both params (a single parameter dict) and multiparams (a list of parameter dicts) are passed simultaneously to the same execution call. SQLAlchemy's execute() accepts one form or the other, not both, so Alembic rejects the combination early.
Solutions
- Pass only one parameter style: use params for a single row, or multiparams for multiple rows.
- If you have a single row, put it in multiparams=[row] and omit params.
- Audit custom impl overrides of _exec to ensure they never forward both arguments.
Example fix
# before
impl._exec(stmt, params={'a': 1}, multiparams=[{'a': 1}, {'a': 2}])
# after
impl._exec(stmt, multiparams=[{'a': 1}, {'a': 2}]) Defensive patterns
Strategy: validation
Validate before calling
def call_exec(impl, construct, params=None, multiparams=None):
if params and multiparams is not None:
raise ValueError('Pass params XOR multiparams, not both')
impl._exec(construct, params=params or {}, multiparams=multiparams) Type guard
def has_single_param_style(params, multiparams) -> bool:
return not (params and multiparams is not None) Prevention
- Never forward both params and multiparams to _exec; choose one.
- For multi-row inserts, use multiparams=[row1, row2] and leave params empty.
- Audit custom DefaultImpl overrides of _exec for this contract.
When it happens
Trigger: Calling impl._exec(construct, params={...}, multiparams=[...]) directly, or higher-level code that forwards both to conn.execute. Typically arises inside custom impl subclasses or patched execution helpers.
Common situations: Custom DefaultImpl subclasses overriding _exec and forwarding both; code that naively merges single-row and multi-row execution into one call.
Related errors
- SQL parameters not allowed with as_sql
- Can't create table in batch mode
- Individual alter column constructs not supported by MySQL
- List expected
- List of dictionaries expected
AI-assisted analysis of sqlalchemy/alembic@5551b5d35f (2026-08-11).
Data as JSON: /api/errors/82bd8acab32bea29.
Report an issue: GitHub.
Appendix: source
Thrown at alembic/ddl/impl.py:245
else:
compile_kw = {}
if TYPE_CHECKING:
assert isinstance(construct, ClauseElement)
compiled = construct.compile(dialect=self.dialect, **compile_kw)
self.static_output(
str(compiled).replace("\t", " ").strip()
+ self.command_terminator
)
return None
else:
conn = self.connection
assert conn is not None
if execution_options:
conn = conn.execution_options(**execution_options)
if params and multiparams is not None:
raise TypeError(
"Can't send params and multiparams at the same time"
)
if multiparams:
return conn.execute(construct, multiparams)
else:
return conn.execute(construct, params)
def execute(
self,
sql: Executable | str,
execution_options: dict[str, Any] | None = None,
) -> None:
self._exec(sql, execution_options)
def alter_column(
self,
table_name: str,View on GitHub (pinned to 5551b5d35f)