{"record":{"id":"e24cdc74aa120c26","repo":"nodejs/node","slug":"argument-must-be-iterable","errorCode":null,"errorMessage":"argument must be iterable","messagePattern":"argument must be iterable","errorType":"exception","errorClass":"FilterArgumentError","httpStatus":null,"severity":"error","filePath":"tools/inspector_protocol/jinja2/filters.py","lineNumber":909,"sourceCode":"    \"\"\"Mark a value as unsafe.  This is the reverse operation for :func:`safe`.\"\"\"\n    return text_type(value)\n\n\ndef do_reverse(value):\n    \"\"\"Reverse the object or return an iterator that iterates over it the other\n    way round.\n    \"\"\"\n    if isinstance(value, string_types):\n        return value[::-1]\n    try:\n        return reversed(value)\n    except TypeError:\n        try:\n            rv = list(value)\n            rv.reverse()\n            return rv\n        except TypeError:\n            raise FilterArgumentError('argument must be iterable')\n\n\n@environmentfilter\ndef do_attr(environment, obj, name):\n    \"\"\"Get an attribute of an object.  ``foo|attr(\"bar\")`` works like\n    ``foo.bar`` just that always an attribute is returned and items are not\n    looked up.\n\n    See :ref:`Notes on subscriptions <notes-on-subscriptions>` for more details.\n    \"\"\"\n    try:\n        name = str(name)\n    except UnicodeError:\n        pass\n    else:\n        try:\n            value = getattr(obj, name)\n        except AttributeError:","sourceCodeStart":891,"sourceCodeEnd":927,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/tools/inspector_protocol/jinja2/filters.py#L891-L927","documentation":"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.","triggerScenarios":"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 }}.","commonSituations":"Passing a scalar where a sequence was expected; a context variable that was unexpectedly None or a single object instead of a list.","solutions":["Ensure the value passed to |reverse is a string, list, tuple, or other iterable.","Guard in the template: {{ value|reverse if value is iterable else value }} or default to an empty list: {{ (value or [])|reverse }}.","Fix the context data so the variable always holds an iterable."],"exampleFix":"{# before #}\n{{ user.age|reverse }}\n\n{# after #}\n{{ user.tags|reverse }}","handlingStrategy":"type-guard","validationCode":"from collections.abc import Iterable\n\ndef ensure_iterable(value):\n    if isinstance(value, (str, bytes)):\n        return value\n    if isinstance(value, Iterable):\n        return value\n    raise TypeError('value passed to reverse must be iterable, got %r' % type(value))","typeGuard":"from collections.abc import Iterable\n\ndef is_reversible(value) -> bool:\n    return isinstance(value, (str, bytes)) or isinstance(value, Iterable)","tryCatchPattern":"from jinja2.exceptions import FilterArgumentError\ntry:\n    out = env.call_filter('reverse', value)\nexcept FilterArgumentError:\n    out = [value] if value is not None else []","preventionTips":["Coerce context variables to lists before passing to |reverse.","Default possibly-None variables to [] with {{ (value or [])|reverse }}.","Type-check scalar vs sequence at the data layer."],"tags":["jinja2","filter","reverse","type-error"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}