{"record":{"id":"07d0fa549eee11bd","repo":"sqlalchemy/alembic","slug":"recreate-may-be-one-of-auto-always-or-never","errorCode":null,"errorMessage":"recreate may be one of 'auto', 'always', or 'never'.","messagePattern":"recreate may be one of 'auto', 'always', or 'never'\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"alembic/operations/batch.py","lineNumber":68,"sourceCode":"    def __init__(\n        self,\n        operations,\n        table_name,\n        schema,\n        recreate,\n        copy_from,\n        table_args,\n        table_kwargs,\n        reflect_args,\n        reflect_kwargs,\n        naming_convention,\n        partial_reordering,\n    ):\n        self.operations = operations\n        self.table_name = table_name\n        self.schema = schema\n        if recreate not in (\"auto\", \"always\", \"never\"):\n            raise ValueError(\n                \"recreate may be one of 'auto', 'always', or 'never'.\"\n            )\n        self.recreate = recreate\n        self.copy_from = copy_from\n        self.table_args = table_args\n        self.table_kwargs = dict(table_kwargs)\n        self.reflect_args = reflect_args\n        self.reflect_kwargs = dict(reflect_kwargs)\n        self.reflect_kwargs.setdefault(\n            \"listeners\", list(self.reflect_kwargs.get(\"listeners\", ()))\n        )\n        self.reflect_kwargs[\"listeners\"].append(\n            (\"column_reflect\", operations.impl.autogen_column_reflect)\n        )\n        self.naming_convention = naming_convention\n        self.partial_reordering = partial_reordering\n        self.batch = []\n","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/sqlalchemy/alembic/blob/5551b5d35f985c99cb8f1af2b3c526b050e4c059/alembic/operations/batch.py#L50-L86","documentation":"BatchOperationsImpl.__init__ raises ValueError when the recreate parameter of batch_alter_table() is not one of 'auto', 'always', or 'never'. The value controls whether the table is rebuilt via copy-and-move: 'auto' decides based on the operation, 'always' forces a rebuild, 'never' forbids it (erroring if the operation requires one).","triggerScenarios":"Calling op.batch_alter_table('t', recreate='sometimes') or passing a typo/boolean/None as recreate.","commonSituations":"Typos in the recreate value; passing recreate=True instead of recreate='always'; outdated tutorial using an invalid string.","solutions":["Use recreate='auto' (default) to let Alembic decide based on the dialect and operations.","Use recreate='always' to force a table rebuild (needed for SQLite and some constrained operations).","Use recreate='never' to forbid rebuilds (only valid on dialects supporting the needed ALTERs natively)."],"exampleFix":"# before\nwith op.batch_alter_table('t', recreate=True) as batch_op:\n    ...\n\n# after\nwith op.batch_alter_table('t', recreate='always') as batch_op:\n    ...","handlingStrategy":"validation","validationCode":"VALID_RECREATE = {'auto', 'always', 'never'}\n\ndef safe_batch(op, table, recreate='auto', **kw):\n    if recreate not in VALID_RECREATE:\n        raise ValueError(f\"recreate must be one of {VALID_RECREATE}\")\n    return op.batch_alter_table(table, recreate=recreate, **kw)","typeGuard":"def is_valid_recreate(value: str) -> bool:\n    return value in {'auto', 'always', 'never'}","tryCatchPattern":null,"preventionTips":["Pass only 'auto', 'always', or 'never' as recreate.","Do not pass booleans; use 'always'/'never' strings.","Default to 'auto' unless you have a specific reason to force or forbid a rebuild."],"tags":["batch-mode","recreate","configuration","ddl"],"backgroundTag":null,"analyzedSha":"5551b5d35f985c99cb8f1af2b3c526b050e4c059","analyzedAt":"2026-08-11T01:38:46.612Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}