nodejs/node · error · TypeError
no items for cycling given
Error message
no items for cycling given
What it means
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.
Source
Thrown at tools/inspector_protocol/jinja2/runtime.py:369
class LoopContextBase(object):
"""A loop context for dynamic iteration."""
_before = _first_iteration
_current = _first_iteration
_after = _last_iteration
_length = None
def __init__(self, undefined, recurse=None, depth0=0):
self._undefined = undefined
self._recurse = recurse
self.index0 = -1
self.depth0 = depth0
self._last_checked_value = missing
def cycle(self, *args):
"""Cycles among the arguments with the current loop index."""
if not args:
raise TypeError('no items for cycling given')
return args[self.index0 % len(args)]
def changed(self, *value):
"""Checks whether the value has changed since the last call."""
if self._last_checked_value != value:
self._last_checked_value = value
return True
return False
first = property(lambda x: x.index0 == 0)
last = property(lambda x: x._after is _last_iteration)
index = property(lambda x: x.index0 + 1)
revindex = property(lambda x: x.length - x.index0)
revindex0 = property(lambda x: x.length - x.index)
depth = property(lambda x: x.depth0 + 1)
@property
def previtem(self):View on GitHub (pinned to 1b2de5e052)
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.
Example fix
// before
{{ loop.cycle(*row_classes) }} {% if row_classes empty %}
// after
{{ loop.cycle(*row_classes) if row_classes else 'default' }} Defensive patterns
Strategy: validation
Validate before calling
# in Python before render
ctx['cycle_items'] = items or ['default']
# or in template: {{ loop.cycle(*items) if items else 'default' }} Type guard
def has_cycle_items(items) -> bool:
return len(items) > 0 Try / catch
# template-level - prefer ignore/conditional; runtime TypeError is not recoverable
{% if row_classes %}{{ loop.cycle(*row_classes) }}{% endif %} Prevention
- Default dynamic cycle lists to a single fallback value.
- Unit-test templates with empty input collections.
- Document that {% cycle %} requires at least one argument.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Tried to call non recursive loop. Maybe you forgot the 'rec
- Loop length for some iterators cannot be lazily calculated i
- at least one item has to be provided
- Template module attribute is unavailable in async mode
- extended multiple times
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/16236d37cb9bbb77.
Report an issue: GitHub.