{"record":{"id":"e29d1d4a19dc69f0","repo":"sqlalchemy/alembic","slug":"template-rendering-failed-see-s-for-a-template-o","errorCode":null,"errorMessage":"Template rendering failed; see %s for a template-oriented traceback.","messagePattern":"Template rendering failed; see (.+?) for a template-oriented traceback\\.","errorType":"exception","errorClass":"CommandError","httpStatus":null,"severity":"error","filePath":"alembic/util/pyfiles.py","lineNumber":41,"sourceCode":"    template_file: str | os.PathLike[str],\n    dest: str | os.PathLike[str],\n    output_encoding: str,\n    *,\n    append_with_newlines: bool = False,\n    **kw: Any,\n) -> None:\n    template = Template(filename=_preserving_path_as_str(template_file))\n    try:\n        output = template.render_unicode(**kw).encode(output_encoding)\n    except:\n        with tempfile.NamedTemporaryFile(suffix=\".txt\", delete=False) as ntf:\n            ntf.write(\n                exceptions.text_error_template()\n                .render_unicode()\n                .encode(output_encoding)\n            )\n            fname = ntf.name\n        raise CommandError(\n            \"Template rendering failed; see %s for a \"\n            \"template-oriented traceback.\" % fname\n        )\n    else:\n        with open(dest, \"ab\" if append_with_newlines else \"wb\") as f:\n            if append_with_newlines:\n                f.write(\"\\n\\n\".encode(output_encoding))\n            f.write(output)\n\n\ndef coerce_resource_to_filename(fname_or_resource: str) -> pathlib.Path:\n    \"\"\"Interpret a filename as either a filesystem location or as a package\n    resource.\n\n    Names that are non absolute paths and contain a colon\n    are interpreted as resources and coerced to a file location.\n\n    \"\"\"","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/sqlalchemy/alembic/blob/5551b5d35f985c99cb8f1af2b3c526b050e4c059/alembic/util/pyfiles.py#L23-L59","documentation":"Raised as CommandError by template_to_file when Mako template rendering fails (pyfiles.py:31-44). The function catches ALL exceptions from template.render_unicode(), writes a detailed Mako-specific traceback to a temporary .txt file, and raises CommandError pointing to that file. The temp file traceback is essential because Mako errors in the original traceback are often opaque. This is used during 'alembic init' to scaffold migration scripts and env.py from templates.","triggerScenarios":"Calling alembic init (which calls template_to_file at command.py) when the Mako template contains syntax errors, references undefined variables, or has broken control flow. Also triggered by custom templates with incorrect ${} expressions or <%block> directives. The bare 'except:' at pyfiles.py:33 catches everything including Mako exceptions.","commonSituations":"Using a custom script_template.mako with Mako syntax errors. Template variables expected by the template aren't passed during init. Upgrading Alembic where the bundled template changed but a cached/custom template is stale. Encoding mismatches in the template file.","solutions":["Open the temp file path mentioned in the error message to read the Mako-oriented traceback — it pinpoints the exact template line.","If using a custom template (script_template.mako), validate its Mako syntax: check ${}, % directives, and <%block> tags.","Ensure all template variables referenced in the template are provided by Alembic's init command.","If using the default bundled template, verify the Alembic installation isn't corrupted: pip install --force-reinstall alembic.","Check the output_encoding argument matches the template's actual encoding."],"exampleFix":"# before: custom script_template.mako has an undefined variable\n## file: my_template.mako\nrevision = '${revision_id}'\ndown_revision = '${undefined_var}'  # Mako error\n\n# after\nrevision = '${revision_id}'\ndown_revision = ${repr(down_revision)}","handlingStrategy":"try-catch","validationCode":"def validate_mako_template(template_path):\n    from mako.template import Template\n    try:\n        t = Template(filename=template_path)\n        # attempt a dry render with dummy vars\n        return True\n    except Exception:\n        return False","typeGuard":null,"tryCatchPattern":"from alembic.util.exc import CommandError\n\ntry:\n    command.init(config, directory)\nexcept CommandError as e:\n    if 'Template rendering failed' in str(e):\n        # extract temp file path from error and read the Mako traceback\n        import re\n        match = re.search(r'see (.+\\.txt) for', str(e))\n        if match:\n            with open(match.group(1)) as f:\n                print(f.read())\n    raise","preventionTips":["Validate custom Mako templates with a test render before using them with alembic init.","Keep templates simple and ensure all referenced variables are provided by Alembic.","After upgrading Alembic, test custom templates against the new bundled template for variable changes."],"tags":["alembic","mako","templates","init","command-error"],"backgroundTag":null,"analyzedSha":"5551b5d35f985c99cb8f1af2b3c526b050e4c059","analyzedAt":"2026-08-11T01:38:46.612Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}