sqlalchemy/alembic · error · ValueError
recreate may be one of 'auto', 'always', or 'never'.
Error message
recreate may be one of 'auto', 'always', or 'never'.
What it means
BatchOperationsImpl.__init__ validates the recreate argument against the fixed set {'auto','always','never'} because these three encode distinct table-rebuild strategies: auto lets the dialect decide, always forces a copy-and-move rebuild, never forbids it. Any other value is a configuration typo that would silently fall through to never.
Source
Thrown at alembic/operations/batch.py:68
def __init__(
self,
operations,
table_name,
schema,
recreate,
copy_from,
table_args,
table_kwargs,
reflect_args,
reflect_kwargs,
naming_convention,
partial_reordering,
):
self.operations = operations
self.table_name = table_name
self.schema = schema
if recreate not in ("auto", "always", "never"):
raise ValueError(
"recreate may be one of 'auto', 'always', or 'never'."
)
self.recreate = recreate
self.copy_from = copy_from
self.table_args = table_args
self.table_kwargs = dict(table_kwargs)
self.reflect_args = reflect_args
self.reflect_kwargs = dict(reflect_kwargs)
self.reflect_kwargs.setdefault(
"listeners", list(self.reflect_kwargs.get("listeners", ()))
)
self.reflect_kwargs["listeners"].append(
("column_reflect", operations.impl.autogen_column_reflect)
)
self.naming_convention = naming_convention
self.partial_reordering = partial_reordering
self.batch = []
View on GitHub (pinned to 44fb345033)
Solutions
- Use recreate='auto' (default) to let the dialect decide based on the operation mix.
- Use recreate='always' to force a full table rebuild (e.g. for SQLite constraint changes).
- Use recreate='never' to forbid rebuild (will error if the operation requires it).
Example fix
// before
with op.batch_alter_table('t', recreate=True) as batch_op: # bool -> ValueError
...
// after
with op.batch_alter_table('t', recreate='always') as batch_op:
... Defensive patterns
Strategy: validation
Validate before calling
if recreate not in ("auto", "always", "never"):
raise ValueError("recreate must be one of 'auto','always','never'") Type guard
def is_valid_recreate(v) -> bool:
return v in ("auto", "always", "never") Prevention
- Pass string literals, not booleans, to recreate.
- Default to recreate='auto' unless you have a specific reason.
- Validate config-driven recreate values before passing them in.
When it happens
Trigger: Passing recreate= to batch_alter_table with a value like 'yes', 'true', 'false', True (bool), None, or a misspelled string.
Common situations: A boolean passed instead of a string (recreate=True); a string copied from a tutorial that used a non-standard token; a config-driven value that wasn't validated upstream.
Related errors
- Invalid plugin expression {name!r}
- Duplicate table keys across multiple MetaData objects: %s
- '%s' is not a valid value for %s; expected 'space', 'newline
- Individual alter column constructs not supported by MySQL
- No support for ALTER of constraints in SQLite dialect. Pleas
AI-assisted analysis of sqlalchemy/alembic@44fb345033 (2026-08-04).
Data as JSON: /data/errors/07d0fa549eee11bd.json.
Report an issue: GitHub.