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

  1. Use `await template.make_module_async(...)` (or get_default_module_async) and read attributes off the returned TemplateModule.
  2. If you need the sync .module path, keep a separate non-async Environment for that template.
  3. 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

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


AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13). Data as JSON: /api/errors/e1accfec4a2f525d. Report an issue: GitHub.