nodejs/node · error · FilterArgumentError

argument must be iterable

Error message

argument must be iterable

What it means

The reverse filter (do_reverse) first tries value[::-1] for strings, then reversed(value), then falls back to list(value).reverse(). If none work — i.e. the value is not iterable (no __iter__ and not a string) — the final list() call raises TypeError which Jinja2 converts to FilterArgumentError.

Source

Thrown at tools/inspector_protocol/jinja2/filters.py:909

    """Mark a value as unsafe.  This is the reverse operation for :func:`safe`."""
    return text_type(value)


def do_reverse(value):
    """Reverse the object or return an iterator that iterates over it the other
    way round.
    """
    if isinstance(value, string_types):
        return value[::-1]
    try:
        return reversed(value)
    except TypeError:
        try:
            rv = list(value)
            rv.reverse()
            return rv
        except TypeError:
            raise FilterArgumentError('argument must be iterable')


@environmentfilter
def do_attr(environment, obj, name):
    """Get an attribute of an object.  ``foo|attr("bar")`` works like
    ``foo.bar`` just that always an attribute is returned and items are not
    looked up.

    See :ref:`Notes on subscriptions <notes-on-subscriptions>` for more details.
    """
    try:
        name = str(name)
    except UnicodeError:
        pass
    else:
        try:
            value = getattr(obj, name)
        except AttributeError:

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Ensure the value passed to |reverse is a string, list, tuple, or other iterable.
  2. Guard in the template: {{ value|reverse if value is iterable else value }} or default to an empty list: {{ (value or [])|reverse }}.
  3. Fix the context data so the variable always holds an iterable.

Example fix

{# before #}
{{ user.age|reverse }}

{# after #}
{{ user.tags|reverse }}
Defensive patterns

Strategy: type-guard

Validate before calling

from collections.abc import Iterable

def ensure_iterable(value):
    if isinstance(value, (str, bytes)):
        return value
    if isinstance(value, Iterable):
        return value
    raise TypeError('value passed to reverse must be iterable, got %r' % type(value))

Type guard

from collections.abc import Iterable

def is_reversible(value) -> bool:
    return isinstance(value, (str, bytes)) or isinstance(value, Iterable)

Try / catch

from jinja2.exceptions import FilterArgumentError
try:
    out = env.call_filter('reverse', value)
except FilterArgumentError:
    out = [value] if value is not None else []

Prevention

When it happens

Trigger: Applying |reverse to a non-iterable value such as an int, float, bool, None, or an object without __iter__ — e.g. {{ 42|reverse }} or {{ none|reverse }}.

Common situations: Passing a scalar where a sequence was expected; a context variable that was unexpectedly None or a single object instead of a list.

Related errors


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