reflex-dev/reflex · error · UntypedVarError

{iterable!s}

Error message

{iterable!s}

What it means

During foreach creation, Reflex renders one child eagerly to collect imports/hooks/styles. If the iterable's element type is untyped (UntypedVarError), it re-raises with the iterable, the 'foreach' context, and a docs link — the root cause is the same as errors 249/251: missing or insufficient type annotations on the iterated var.

Source

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

            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
        return component

    def _render(self) -> IterTag:
        props = {}

        render_sig = inspect.signature(self.render_fn)
        params = list(render_sig.parameters.values())

        # Validate the render function signature.
        if len(params) == 0 or len(params) > 2:
            msg = (
                "Expected 1 or 2 parameters in foreach render function, got "
                f"{[p.name for p in params]}. See "
                "https://reflex.dev/docs/library/dynamic-rendering/foreach/"

View on GitHub (pinned to 45b8ed5ab7)

Solutions

  1. Fully annotate nested types: matrix: list[list[int]] = []
  2. Annotate computed vars: @rx.var def items(self) -> list[str]: ...
  3. Check the linked docs page for supported iterable types

Example fix

# before
@rx.var
def rows(self):
    return self.data.values()
# after
@rx.var
def rows(self) -> list[str]:
    return list(self.data.values())
Defensive patterns

Strategy: type-guard

Validate before calling

assert State.rows._var_type is not None and str(State.rows._var_type) != 'Any', 'fully annotate nested iterables'

Type guard

def fully_typed(v) -> bool:
    import typing
    t = getattr(v, '_var_type', None)
    return t is not None and t is not typing.Any and 'Any' not in str(t)

Prevention

When it happens

Trigger: Foreach over a nested var whose element type resolves to untyped, e.g. rows: list[list] = [], or vars produced by untyped state operations (dict.values() on a bare-dict annotation).

Common situations: Nested containers annotated only at the outer level; vars returned by untyped computed vars (no return annotation on @rx.var).

Related errors


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