{"record":{"id":"16236d37cb9bbb77","repo":"nodejs/node","slug":"no-items-for-cycling-given","errorCode":null,"errorMessage":"no items for cycling given","messagePattern":"no items for cycling given","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"tools/inspector_protocol/jinja2/runtime.py","lineNumber":369,"sourceCode":"class LoopContextBase(object):\n    \"\"\"A loop context for dynamic iteration.\"\"\"\n\n    _before = _first_iteration\n    _current = _first_iteration\n    _after = _last_iteration\n    _length = None\n\n    def __init__(self, undefined, recurse=None, depth0=0):\n        self._undefined = undefined\n        self._recurse = recurse\n        self.index0 = -1\n        self.depth0 = depth0\n        self._last_checked_value = missing\n\n    def cycle(self, *args):\n        \"\"\"Cycles among the arguments with the current loop index.\"\"\"\n        if not args:\n            raise TypeError('no items for cycling given')\n        return args[self.index0 % len(args)]\n\n    def changed(self, *value):\n        \"\"\"Checks whether the value has changed since the last call.\"\"\"\n        if self._last_checked_value != value:\n            self._last_checked_value = value\n            return True\n        return False\n\n    first = property(lambda x: x.index0 == 0)\n    last = property(lambda x: x._after is _last_iteration)\n    index = property(lambda x: x.index0 + 1)\n    revindex = property(lambda x: x.length - x.index0)\n    revindex0 = property(lambda x: x.length - x.index)\n    depth = property(lambda x: x.depth0 + 1)\n\n    @property\n    def previtem(self):","sourceCodeStart":351,"sourceCodeEnd":387,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/tools/inspector_protocol/jinja2/runtime.py#L351-L387","documentation":"Raised by LoopContext.cycle(*args) when called with zero arguments. The {% cycle %} helper in templates cycles among the supplied values using the current loop index; with no values there is nothing to cycle through, so the runtime rejects it with TypeError.","triggerScenarios":"A template that calls {{ loop.cycle() }} with no arguments. Programmatic use of a LoopContext instance where the cycle list is computed at runtime and turns out empty (e.g. loop.cycle(*items) where items is []). Confusion between the loop.cycle method and the standalone jinja2.utils.Cycler.","commonSituations":"Dynamic cycle lists built from a variable that is sometimes empty. Refactoring a fixed {% cycle 'a','b' %} into a data-driven form and forgetting the empty case. Migration from another template engine where cycle with no args is a no-op.","solutions":["Provide at least one argument to loop.cycle, e.g. {{ loop.cycle('even','odd') }}.","Guard dynamic cycles: {% if items %}{{ loop.cycle(*items) }}{% endif %} or default to a single value.","Replace an empty cycle with a literal or omit the call entirely if there is nothing to alternate.","Unit-test templates against empty input sets."],"exampleFix":"// before\n{{ loop.cycle(*row_classes) }}  {% if row_classes empty %}\n// after\n{{ loop.cycle(*row_classes) if row_classes else 'default' }}","handlingStrategy":"validation","validationCode":"# in Python before render\nctx['cycle_items'] = items or ['default']\n# or in template: {{ loop.cycle(*items) if items else 'default' }}","typeGuard":"def has_cycle_items(items) -> bool:\n    return len(items) > 0","tryCatchPattern":"# template-level - prefer ignore/conditional; runtime TypeError is not recoverable\n{% if row_classes %}{{ loop.cycle(*row_classes) }}{% endif %}","preventionTips":["Default dynamic cycle lists to a single fallback value.","Unit-test templates with empty input collections.","Document that {% cycle %} requires at least one argument."],"tags":["jinja2","runtime","loop","cycle","template"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}