nodejs/node · error · TypeError

this loader cannot iterate over all templates

Error message

this loader cannot iterate over all templates

What it means

BaseLoader.list_templates() intentionally raises TypeError('this loader cannot iterate over all templates') as its default. Listing every template is not meaningful for all loader backends, so concrete loaders must opt in by overriding list_templates; otherwise the operation is unsupported.

Source

Thrown at tools/inspector_protocol/jinja2/loaders.py:97

        otherwise `None`.  The filename is used by python for the tracebacks
        if no loader extension is used.

        The last item in the tuple is the `uptodate` function.  If auto
        reloading is enabled it's always called to check if the template
        changed.  No arguments are passed so the function must store the
        old state somewhere (for example in a closure).  If it returns `False`
        the template will be reloaded.
        """
        if not self.has_source_access:
            raise RuntimeError('%s cannot provide access to the source' %
                               self.__class__.__name__)
        raise TemplateNotFound(template)

    def list_templates(self):
        """Iterates over all templates.  If the loader does not support that
        it should raise a :exc:`TypeError` which is the default behavior.
        """
        raise TypeError('this loader cannot iterate over all templates')

    @internalcode
    def load(self, environment, name, globals=None):
        """Loads a template.  This method looks up the template in the cache
        or loads one by calling :meth:`get_source`.  Subclasses should not
        override this method as loaders working on collections of other
        loaders (such as :class:`PrefixLoader` or :class:`ChoiceLoader`)
        will not call this method but `get_source` directly.
        """
        code = None
        if globals is None:
            globals = {}

        # first we try to get the source for this template together
        # with the filename and the uptodate function.
        source, filename, uptodate = self.get_source(environment, name)

        # try to load the code from the bytecode cache if there is a

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Override list_templates() in your loader subclass to return a list of names.
  2. Use a loader that supports enumeration (FileSystemLoader, PackageLoader, DictLoader, PrefixLoader, ChoiceLoader) if you need listing.
  3. Guard callers by hasattr(loader, 'list_templates') or by catching TypeError when enumeration is optional.

Example fix

# before
class MyLoader(BaseLoader):
    pass
MyLoader().list_templates()  # TypeError

# after
class MyLoader(BaseLoader):
    def list_templates(self):
        return sorted(self._db.keys())
Defensive patterns

Strategy: type-guard

Validate before calling

from jinja2 import BaseLoader

def loader_can_list(loader) -> bool:
    return type(loader).list_templates is not BaseLoader.list_templates

Type guard

from jinja2 import BaseLoader

def supports_list_templates(loader) -> bool:
    return type(loader).list_templates is not BaseLoader.list_templates

Try / catch

try:
    names = env.list_templates()
except TypeError:
    names = []  # enumeration unsupported by this loader

Prevention

When it happens

Trigger: Calling environment.list_templates() or loader.list_templates() on a loader that does not implement enumeration (e.g., a custom loader, or a loader backed by a source that cannot be walked).

Common situations: Building admin/debug tooling that enumerates available templates; running tests that call list_templates against a minimal custom loader.

Related errors


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