reflex-dev/reflex · error · VarTypeError

The function passed to reduce should take exactly two argume

Error message

The function passed to reduce should take exactly two arguments (accumulator, element).

What it means

ArrayVar.reduce() compiles the passed Python reducer into a JS reduce callback, which must accept exactly two parameters: the accumulator and the current element. Any other arity raises VarTypeError.

Source

Thrown at packages/reflex-base/src/reflex_base/vars/sequence.py:560

        an empty array raises a TypeError at runtime.

        Args:
            fn: The reducer, taking the accumulator and the current element.
            initial: The initial accumulator value.

        Returns:
            The reduced value.

        Raises:
            VarTypeError: If the function does not take exactly two arguments.
        """
        from .function import ArgsFunctionOperation

        if not callable(fn):
            raise_unsupported_operand_types("reduce", (type(self), type(fn)))
        if len(inspect.signature(fn).parameters) != 2:
            msg = "The function passed to reduce should take exactly two arguments (accumulator, element)."
            raise VarTypeError(msg)

        element = self._element_placeholder()
        initial_var = None if isinstance(initial, types.Unset) else Var.create(initial)
        accumulator_type = (
            element._var_type if initial_var is None else initial_var._var_type
        )
        accumulator = Var(
            _js_expr=get_unique_variable_name(),
            _var_type=accumulator_type,
        ).guess_type()
        return_expr = Var.create(fn(accumulator, element))
        function_var = ArgsFunctionOperation.create(
            (accumulator._js_expr, element._js_expr),
            return_expr,
            _var_type=Callable[
                [accumulator_type, element._var_type], return_expr._var_type
            ],
        )

View on GitHub (pinned to 45b8ed5ab7)

Solutions

  1. Use exactly two parameters: lambda accumulator, element: ....
  2. If you need the index, track it via a different mechanism (computed var with enumerate).
  3. Ensure no default/keyword-only params inflate the signature count.

Example fix

# before
State.nums.reduce(lambda acc, x, i: acc + x)

# after
State.nums.reduce(lambda acc, x: acc + x, initial=0)
Defensive patterns

Strategy: validation

Validate before calling

import inspect

def is_binary_reducer(fn) -> bool:
    return len(inspect.signature(fn).parameters) == 2

Type guard

import inspect

def binary_callback(fn) -> bool:
    return callable(fn) and len(inspect.signature(fn).parameters) == 2

Prevention

When it happens

Trigger: Passing a one-arg function to reduce (`items.reduce(lambda x: ...)`), a three-arg function (trying to include the index like JS reduce), or a function using *args (inspect.signature().parameters count != 2).

Common situations: Copy-pasting JS reduce((acc, el, i) => ...) into Python lambdas; reusing min/max style helpers that take variadic args; wrapping reducers in decorators that alter signatures.

Related errors


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