nodejs/node · error · RuntimeError
Template module attribute is unavailable in async mode
Error message
Template module attribute is unavailable in async mode
What it means
Raised by the wrapped _get_default_module (asyncsupport.py) when template.module is accessed on a Template whose environment is in async mode. In async mode the module must be built by awaiting make_module_async / get_default_module_async, so the synchronous .module property is deliberately disabled.
Source
Thrown at tools/inspector_protocol/jinja2/asyncsupport.py:127
if not self._environment.is_async:
return original_invoke(self, arguments, autoescape)
return async_invoke(self, arguments, autoescape)
return update_wrapper(_invoke, original_invoke)
@internalcode
async def get_default_module_async(self):
if self._module is not None:
return self._module
self._module = rv = await self.make_module_async()
return rv
def wrap_default_module(original_default_module):
@internalcode
def _get_default_module(self):
if self.environment.is_async:
raise RuntimeError('Template module attribute is unavailable '
'in async mode')
return original_default_module(self)
return _get_default_module
async def make_module_async(self, vars=None, shared=False, locals=None):
context = self.new_context(vars, shared, locals)
body_stream = []
async for item in self.root_render_func(context):
body_stream.append(item)
return TemplateModule(self, context, body_stream)
def patch_template():
from jinja2 import Template
Template.generate = wrap_generate_func(Template.generate)
Template.generate_async = update_wrapper(
generate_async, Template.generate_async)View on GitHub (pinned to 1b2de5e052)
Solutions
- Use `await template.make_module_async(...)` (or get_default_module_async) and read attributes off the returned TemplateModule.
- If you need the sync .module path, keep a separate non-async Environment for that template.
- Refactor the consuming code to call the rendered block functions through the async module API.
Example fix
# before m = template.module # raises in async mode m.my_block() # after m = await template.make_module_async() m.my_block()
Defensive patterns
Strategy: validation
Validate before calling
async def get_module(template):
if template.environment.is_async:
return await template.make_module_async()
return template.module Type guard
def is_async_env(template) -> bool:
return getattr(template.environment, 'is_async', False) Prevention
- Never read .module directly in code that may run in async mode — route through a helper.
- Keep sync and async Environments separate if both code paths exist.
- Prefer await make_module_async() uniformly in async apps.
When it happens
Trigger: Accessing `template.module` (or `{% import %}`-driven module access at the API level) while environment.is_async is True; calling code that was written for sync Jinja2 against an async-enabled Environment.
Common situations: Porting code that reads template.module.<block>() to an async server; a third-party helper that unconditionally touches .module being reused in an async app.
Related errors
- Loop length for some iterators cannot be lazily calculated i
- The environment was not created with async mode enabled.
- extended multiple times
- cannot assign attribute on non-namespace object
- no loader for this environment specified
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/e1accfec4a2f525d.
Report an issue: GitHub.