nodejs/node · error · TypeError
Can't compile non template nodes
Error message
Can't compile non template nodes
What it means
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.
Source
Thrown at tools/inspector_protocol/jinja2/compiler.py:78
supports_yield_from = True
def optimizeconst(f):
def new_func(self, node, frame, **kwargs):
# Only optimize if the frame is not volatile
if self.optimized and not frame.eval_ctx.volatile:
new_node = self.optimizer.visit(node, frame.eval_ctx)
if new_node != node:
return self.visit(new_node, frame)
return f(self, node, frame, **kwargs)
return update_wrapper(new_func, f)
def generate(node, environment, name, filename, stream=None,
defer_init=False, optimized=True):
"""Generate the python source for a node tree."""
if not isinstance(node, nodes.Template):
raise TypeError('Can\'t compile non template nodes')
generator = environment.code_generator_class(environment, name, filename,
stream, defer_init,
optimized)
generator.visit(node)
if stream is None:
return generator.stream.getvalue()
def has_safe_repr(value):
"""Does the node have a safe representation?"""
if value is None or value is NotImplemented or value is Ellipsis:
return True
if type(value) in (bool, int, float, complex, range_type, Markup) + string_types:
return True
if type(value) in (tuple, list, set, frozenset):
for item in value:
if not has_safe_repr(item):
return FalseView on GitHub (pinned to 1b2de5e052)
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.
Example fix
# before
code = generate(nodes.Output([nodes.Data('hi')]), env, 'x', 'x.html')
# after
tpl = nodes.Template(body=[nodes.Output([nodes.Data('hi')])], lineno=1)
code = generate(tpl, env, 'x', 'x.html') Defensive patterns
Strategy: validation
Validate before calling
from jinja2 import nodes, compiler
def safe_generate(node, env, name, filename, **kw):
if not isinstance(node, nodes.Template):
node = nodes.Template(body=[node], lineno=1)
return compiler.generate(node, env, name, filename, **kw) Type guard
from jinja2 import nodes
def is_template_node(node) -> bool:
return isinstance(node, nodes.Template) Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Can't create internal names. Use the `free_identifier` meth
- can't create custom node types
- Unable to locate a compiler for preprocessing assembly
- Preprocessing failed: {command}
- Failed to parse config file "%s": %s
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/7a722c452f23d97b.
Report an issue: GitHub.