nodejs/node · error · TypeError

either extensions or filter_func can be passed, but not both

Error message

either extensions or filter_func can be passed, but not both

What it means

Raised by Environment.list_templates (jinja2 environment.py) when both `extensions` and `filter_func` keyword arguments are supplied. The method supports filtering template names by either a list of file extensions or a custom predicate function, but not both simultaneously — supplying both is an ambiguous request and is rejected.

Source

Thrown at tools/inspector_protocol/jinja2/environment.py:752

        """Returns a list of templates for this environment.  This requires
        that the loader supports the loader's
        :meth:`~BaseLoader.list_templates` method.

        If there are other files in the template folder besides the
        actual templates, the returned list can be filtered.  There are two
        ways: either `extensions` is set to a list of file extensions for
        templates, or a `filter_func` can be provided which is a callable that
        is passed a template name and should return `True` if it should end up
        in the result list.

        If the loader does not support that, a :exc:`TypeError` is raised.

        .. versionadded:: 2.4
        """
        x = self.loader.list_templates()
        if extensions is not None:
            if filter_func is not None:
                raise TypeError('either extensions or filter_func '
                                'can be passed, but not both')
            filter_func = lambda x: '.' in x and \
                                    x.rsplit('.', 1)[1] in extensions
        if filter_func is not None:
            x = list(ifilter(filter_func, x))
        return x

    def handle_exception(self, exc_info=None, rendered=False, source_hint=None):
        """Exception handling helper.  This is used internally to either raise
        rewritten exceptions or return a rendered traceback for the template.
        """
        global _make_traceback
        if exc_info is None:
            exc_info = sys.exc_info()

        # the debugging module is imported when it's used for the first time.
        # we're doing a lot of stuff there and for applications that do not
        # get any exceptions in template rendering there is no need to load

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Pass only one of the two; if you need both constraints, fold them into a single filter_func.
  2. In wrapper code, assert/branch on which kwarg is set before forwarding.
  3. Combine: `filter_func = lambda name: name.endswith('.html') and my_fn(name)`.

Example fix

# before
env.list_templates(extensions=['html'], filter_func=custom)
# after
env.list_templates(filter_func=lambda n: n.endswith('.html') and custom(n))
Defensive patterns

Strategy: validation

Validate before calling

def list_templates(env, extensions=None, filter_func=None):
    if extensions is not None and filter_func is not None:
        if extensions:
            exts = set(extensions)
            filter_func = (lambda f: (lambda n: n.rsplit('.',1)[-1] in exts and f(n)))(filter_func)
        extensions = None
    return env.list_templates(extensions=extensions, filter_func=filter_func)

Prevention

When it happens

Trigger: Calling `env.list_templates(extensions=['html'], filter_func=my_fn)`; wrapping list_templates and forwarding both optional kwargs when both happen to be set.

Common situations: Helper functions that expose both options and pass them straight through; configuration-driven code that builds kwargs from settings and ends up populating both.

Related errors


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