reflex-dev/reflex · error · ForeachVarError

Could not foreach over var `{iterable!s}` of type {iterable.

Error message

Could not foreach over var `{iterable!s}` of type {iterable._var_type}. See https://reflex.dev/docs/library/dynamic-rendering/foreach/

What it means

After unwrapping (objects → entries, strings → split), `rx.foreach` requires an ArrayVar — an iterable whose type is a list/array. If the var's type is, say, a plain non-iterable type, a set, a generator annotation, or something foreach cannot convert to ArrayVar, it raises ForeachVarError.

Source

Thrown at packages/reflex-components-core/src/reflex_components_core/core/foreach.py:103

        if (
            hasattr(render_fn, "__qualname__")
            and render_fn.__qualname__ == ComponentState.create.__qualname__
        ):
            msg = "Using a ComponentState as `render_fn` inside `rx.foreach` is not supported yet."
            raise TypeError(msg)

        if isinstance(iterable, ObjectVar):
            iterable = iterable.entries()

        if isinstance(iterable, StringVar):
            iterable = iterable.split()

        if not isinstance(iterable, ArrayVar):
            msg = (
                f"Could not foreach over var `{iterable!s}` of type {iterable._var_type}. "
                "See https://reflex.dev/docs/library/dynamic-rendering/foreach/"
            )
            raise ForeachVarError(msg)

        if types.is_optional(iterable._var_type):
            iterable = cond(iterable, iterable, [])

        component = cls._create(
            children=[],
            iterable=iterable,
            render_fn=render_fn,
        )
        try:
            # Keep a ref to a rendered component to determine correct imports/hooks/styles.
            component.children = [component._render().render_component()]
        except UntypedVarError as e:
            raise UntypedVarError(
                iterable,
                "foreach",
                "https://reflex.dev/docs/library/dynamic-rendering/foreach/",
            ).with_traceback(e.__traceback__) from None

View on GitHub (pinned to 45b8ed5ab7)

Solutions

  1. Annotate the state field as a list: items: list[str] = []
  2. Pass an actual iterable var: rx.foreach(State.tags, ...) where tags: list[str]
  3. Convert other containers to lists in an event handler before rendering

Example fix

# before
class State(rx.State):
    tags: set[str] = set()
rx.foreach(State.tags, lambda t: rx.badge(t))
# after
class State(rx.State):
    tags: list[str] = []
rx.foreach(State.tags, lambda t: rx.badge(t))
Defensive patterns

Strategy: type-guard

Validate before calling

from reflex.vars import ArrayVar
assert isinstance(State.tags, ArrayVar) or str(getattr(State.tags, '_var_type', '')).startswith(('list', 'dict')), 'need list-typed var'

Type guard

def is_foreachable(v) -> bool:
    from reflex.vars import ArrayVar
    return isinstance(v, ArrayVar) or str(getattr(v, '_var_type', type(v))).startswith(('list', 'dict'))

Prevention

When it happens

Trigger: `rx.foreach(State.count, ...)` where count: int; annotating items as a set or custom non-list iterable; foreach over a var typed as tuple in some unsupported path.

Common situations: Passing the wrong state var to foreach; annotating with non-list container types; refactoring a list field into a scalar and forgetting the foreach call.

Related errors


AI-assisted analysis of reflex-dev/reflex@45b8ed5ab7 (2026-08-28). Data as JSON: /api/errors/e4bf45ed296af571. Report an issue: GitHub.