{"record":{"id":"7a722c452f23d97b","repo":"nodejs/node","slug":"can-t-compile-non-template-nodes","errorCode":null,"errorMessage":"Can't compile non template nodes","messagePattern":"Can't compile non template nodes","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"tools/inspector_protocol/jinja2/compiler.py","lineNumber":78,"sourceCode":"    supports_yield_from = True\n\n\ndef optimizeconst(f):\n    def new_func(self, node, frame, **kwargs):\n        # Only optimize if the frame is not volatile\n        if self.optimized and not frame.eval_ctx.volatile:\n            new_node = self.optimizer.visit(node, frame.eval_ctx)\n            if new_node != node:\n                return self.visit(new_node, frame)\n        return f(self, node, frame, **kwargs)\n    return update_wrapper(new_func, f)\n\n\ndef generate(node, environment, name, filename, stream=None,\n             defer_init=False, optimized=True):\n    \"\"\"Generate the python source for a node tree.\"\"\"\n    if not isinstance(node, nodes.Template):\n        raise TypeError('Can\\'t compile non template nodes')\n    generator = environment.code_generator_class(environment, name, filename,\n                                                 stream, defer_init,\n                                                 optimized)\n    generator.visit(node)\n    if stream is None:\n        return generator.stream.getvalue()\n\n\ndef has_safe_repr(value):\n    \"\"\"Does the node have a safe representation?\"\"\"\n    if value is None or value is NotImplemented or value is Ellipsis:\n        return True\n    if type(value) in (bool, int, float, complex, range_type, Markup) + string_types:\n        return True\n    if type(value) in (tuple, list, set, frozenset):\n        for item in value:\n            if not has_safe_repr(item):\n                return False","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/tools/inspector_protocol/jinja2/compiler.py#L60-L96","documentation":"Raised by compiler.generate (jinja2 compiler.py) when the AST node handed to the code generator is not an instance of nodes.Template. generate() expects the whole template AST (whose root is always a Template node produced by the parser); passing any other node type — a single statement, an expression, or a list — is a programmer error.","triggerScenarios":"Calling jinja2.compiler.generate() directly with a bare node (e.g. nodes.Output, nodes.For, nodes.Assign) instead of a nodes.Template wrapping it; constructing an AST by hand and forgetting the Template wrapper; calling the compiler on a sub-tree extracted from a parsed template.","commonSituations":"Library/integration authors building custom Jinja2 tooling (linters, optimizers, transformers) that pass subtrees to the compiler; misuse of the internal compile pipeline instead of Environment.compile.","solutions":["Wrap your node(s) in nodes.Template(body=[...], lineno=1) before calling generate.","Prefer the public Environment.compile(source) / env.from_string(), which parse correctly into a Template node.","If transforming an existing AST, operate on template.body but recompile via the Template root."],"exampleFix":"# before\ncode = generate(nodes.Output([nodes.Data('hi')]), env, 'x', 'x.html')\n# after\ntpl = nodes.Template(body=[nodes.Output([nodes.Data('hi')])], lineno=1)\ncode = generate(tpl, env, 'x', 'x.html')","handlingStrategy":"validation","validationCode":"from jinja2 import nodes, compiler\n\ndef safe_generate(node, env, name, filename, **kw):\n    if not isinstance(node, nodes.Template):\n        node = nodes.Template(body=[node], lineno=1)\n    return compiler.generate(node, env, name, filename, **kw)","typeGuard":"from jinja2 import nodes\ndef is_template_node(node) -> bool:\n    return isinstance(node, nodes.Template)","tryCatchPattern":null,"preventionTips":["Prefer Environment.compile / from_string over calling the compiler directly.","If building AST by hand, always wrap the body in nodes.Template.","Keep AST transforms on template.body but recompile via the root."],"tags":["jinja2","compiler","ast"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}