{"id":"92f2922247de286a","repo":"pallets/flask","slug":"template","errorCode":null,"errorMessage":"{template}","messagePattern":"(.+?)","errorType":"exception","errorClass":"TemplateNotFound","httpStatus":null,"severity":"error","filePath":"src/flask/templating.py","lineNumber":86,"sourceCode":"        rv: tuple[str, str | None, t.Callable[[], bool] | None] | None\n        trv: None | (tuple[str, str | None, t.Callable[[], bool] | None]) = None\n\n        for srcobj, loader in self._iter_loaders(template):\n            try:\n                rv = loader.get_source(environment, template)\n                if trv is None:\n                    trv = rv\n            except TemplateNotFound:\n                rv = None\n            attempts.append((loader, srcobj, rv))\n\n        from .debughelpers import explain_template_loading_attempts\n\n        explain_template_loading_attempts(self.app, template, attempts)\n\n        if trv is not None:\n            return trv\n        raise TemplateNotFound(template)\n\n    def _get_source_fast(\n        self, environment: BaseEnvironment, template: str\n    ) -> tuple[str, str | None, t.Callable[[], bool] | None]:\n        for _srcobj, loader in self._iter_loaders(template):\n            try:\n                return loader.get_source(environment, template)\n            except TemplateNotFound:\n                continue\n        raise TemplateNotFound(template)\n\n    def _iter_loaders(self, template: str) -> t.Iterator[tuple[Scaffold, BaseLoader]]:\n        loader = self.app.jinja_loader\n        if loader is not None:\n            yield self.app, loader\n\n        for blueprint in self.app.iter_blueprints():\n            loader = blueprint.jinja_loader","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/pallets/flask/blob/6a2f545bfd8ed31e19066a299296917e034aca58/src/flask/templating.py#L68-L104","documentation":"A `jinja2.TemplateNotFound` raised by Flask's DispatchingJinjaLoader in `_get_source_explained` (used when `EXPLAIN_TEMPLATE_LOADING=True`). Flask tried every loader — the app's `templates/` folder and each registered blueprint's template folder — and none could supply the named template. In this explain path, Flask first logs a detailed report of every loader attempted before raising.","triggerScenarios":"`render_template('name.html')` (or `render_template_string` extending a missing template, `{% include %}`/`{% extends %}` of a missing file) when the file doesn't exist in the app's template_folder or any blueprint's template_folder, with EXPLAIN_TEMPLATE_LOADING enabled.","commonSituations":"Typo or wrong case in the template filename (case-sensitive on Linux, not on macOS/Windows dev machines); templates placed next to the module instead of in `templates/`; blueprint created without `template_folder=` set; package installed without including template files (missing package_data/MANIFEST.in); wrong `template_folder` path relative to the app root.","solutions":["Check the explain-template-loading log output just emitted — it lists every loader and path Flask searched; put the file where one of those paths points.","Fix the filename/case in `render_template()` to exactly match the file on disk.","Pass `template_folder='templates'` when constructing the Blueprint if the template lives with the blueprint.","For installed packages, ensure templates are included in the distribution (package_data or MANIFEST.in)."],"exampleFix":"# before\nbp = Blueprint(\"admin\", __name__)\nrender_template(\"admin/Index.html\")\n\n# after\nbp = Blueprint(\"admin\", __name__, template_folder=\"templates\")\nrender_template(\"admin/index.html\")  # matches on-disk case","handlingStrategy":"try-catch","validationCode":"import os\ntpl = 'user/profile.html'\nexists = os.path.exists(os.path.join(app.root_path, app.template_folder, tpl))","typeGuard":"def template_exists(app, name):\n    return app.jinja_env.get_or_select_template is not None and name in app.jinja_env.list_templates()","tryCatchPattern":"from jinja2 import TemplateNotFound\ntry:\n    return render_template('page.html')\nexcept TemplateNotFound:\n    abort(404)","preventionTips":["Never build template names from user input; if you must, whitelist against app.jinja_env.list_templates()","Keep templates in the folder matching template_folder and mind blueprint template search order","Run the app with EXPLAIN_TEMPLATE_LOADING=True when debugging which loader/path was searched","Catch jinja2.TemplateNotFound at route level and return a proper 404 rather than a 500"],"tags":["flask","jinja2","templates","python"],"analyzedSha":"6a2f545bfd8ed31e19066a299296917e034aca58","analyzedAt":"2026-07-31T19:13:49.921Z","schemaVersion":2}