reflex-dev/reflex · error · ForeachRenderError
Expected 1 or 2 parameters in foreach render function, got {
Error message
Expected 1 or 2 parameters in foreach render function, got {[p.name for p in params]}. See https://reflex.dev/docs/library/dynamic-rendering/foreach/ What it means
The render function passed to `rx.foreach` may accept 1 parameter (the item) or 2 parameters (item, index) for lists, or (key, value) for dicts. Zero or more than two parameters — including params with defaults counting toward the signature — raise ForeachRenderError.
Source
Thrown at packages/reflex-components-core/src/reflex_components_core/core/foreach.py:137
"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/"
)
raise ForeachRenderError(msg)
if len(params) >= 1:
# Determine the arg var name based on the params accepted by render_fn.
props["arg_var_name"] = params[0].name + FIELD_MARKER
if len(params) == 2:
# Determine the index var name based on the params accepted by render_fn.
props["index_var_name"] = params[1].name + FIELD_MARKER
else:
render_fn = self.render_fn
# Otherwise, use a deterministic index, based on the render function bytecode.
if (render_fn_code := getattr(render_fn, "__code__", None)) is not None:
code_hash = md5(render_fn_code.co_code).hexdigest()
elif isinstance(render_fn, functools.partial):
code_hash = md5(render_fn.func.__code__.co_code).hexdigest()
else:
code_hash = md5(repr(render_fn).encode()).hexdigest()
props["index_var_name"] = f"index_{code_hash}"View on GitHub (pinned to 45b8ed5ab7)
Solutions
- Use exactly one parameter: rx.foreach(State.items, lambda item: rx.text(item))
- Or two for index access: rx.foreach(State.items, lambda item, i: rx.text(f'{i}: {item}'))
- Wrap multi-arg builders in a closure: lambda item: make_row(item, 'extra')
Example fix
# before def render_row(item, index, is_admin): ... rx.foreach(State.items, render_row) # after rx.foreach(State.items, lambda item, i: render_row(item, i, State.is_admin))
Defensive patterns
Strategy: validation
Validate before calling
import inspect
params = inspect.signature(render_fn).parameters
assert 1 <= len(params) <= 2, f'render fn takes 1-2 params, got {len(params)}' Type guard
def valid_foreach_fn(fn) -> bool:
import inspect
return 1 <= len(inspect.signature(fn).parameters) <= 2 Prevention
- Keep foreach render fns to lambda item / lambda item, index
- Use closures to bind extra arguments
When it happens
Trigger: `rx.foreach(State.items, lambda: rx.text('x'))`; a render def with three params like def render(item, index, extra); accidentally passing a component class constructor expecting many args.
Common situations: Reusing a component factory function with extra arguments; refactoring a render fn and leaving stale parameters.
Related errors
- The render function must take 2 arguments.
- The render function must return a component.
- Could not foreach over var `{iterable!s}` of type Any. (If y
- Using a ComponentState as `render_fn` inside `rx.foreach` is
- Could not foreach over var `{iterable!s}` of type {iterable.
AI-assisted analysis of reflex-dev/reflex@45b8ed5ab7 (2026-08-28).
Data as JSON: /api/errors/d840a44cca2ba475.
Report an issue: GitHub.