infiniflow/ragflow · error · Exception

{} must be an array, but its type is {}

Error message

{} must be an array, but its type is {}

What it means

Raised by the IterationItem component when the variable referenced by the parent Iteration component's items_ref does not resolve to a Python list. The component fetches the value via canvas.get_variable_value(items_ref) and strictly isinstance-checks it against list before iterating.

Source

Thrown at agent/component/iterationitem.py:45

        return True


class IterationItem(ComponentBase, ABC):
    component_name = "IterationItem"

    def __init__(self, canvas, id, param: ComponentParamBase):
        super().__init__(canvas, id, param)
        self._idx = 0

    def _invoke(self, **kwargs):
        if self.check_if_canceled("IterationItem processing"):
            return

        parent = self.get_parent()
        arr = self._canvas.get_variable_value(parent._param.items_ref)
        if not isinstance(arr, list):
            self._idx = -1
            raise Exception(parent._param.items_ref + " must be an array, but its type is " + str(type(arr)))

        if self._idx > 0:
            if self.check_if_canceled("IterationItem processing"):
                return
            self.output_collation()

        if self._idx >= len(arr):
            self._idx = -1
            return

        if self.check_if_canceled("IterationItem processing"):
            return

        current_item = arr[self._idx]
        self.set_output("item", current_item)
        # Keep `result` as a compatibility alias because existing DSL examples
        # and downstream references may still consume IterationItem via `@result`.
        self.set_output("result", current_item)

View on GitHub (pinned to 554fb1133a)

Solutions

  1. Make the upstream producer emit an actual array: parse JSON output in a Code component (json.loads) before feeding Iteration.
  2. Verify the items_ref selector points to a component output that is a list (e.g. Iteration's aggregated output is a dict — select the specific list field).
  3. If the value may legitimately be a single item, wrap it: use a Code component to return [value] when not isinstance(value, list).

Example fix

# before: LLM output (str) wired straight into Iteration items_ref
# after: Code component normalizes to list
import json
def main(arg0):
    v = arg0
    if isinstance(v, str):
        v = json.loads(v)
    if not isinstance(v, list):
        v = [v]
    return v
Defensive patterns

Strategy: type-guard

Validate before calling

arr = canvas.get_variable_value(items_ref)
if not isinstance(arr, list):
    raise SystemError(f'{items_ref} is {type(arr).__name__}, expected list')  # fail early with context

Type guard

def is_array(v) -> bool:
    return isinstance(v, list)

Try / catch

try:
    iteration_item._invoke()
except Exception as e:
    if 'must be an array' in str(e):
        # fix upstream producer to emit a list, then re-run canvas
        ...

Prevention

When it happens

Trigger: An Iteration component whose items_ref points to: a string (iterating characters was not intended), a dict, None (upstream component produced no output yet), or a generator/other non-list object. Also occurs when the referenced component ID no longer exists so the resolution returns a placeholder.

Common situations: Upstream LLM/Code component returns a JSON string that was never parsed into a list; upstream component renamed/deleted so the selector dangles; the aggregate output of another iteration (which may be a dict of collected fields) is used directly as items.

Related errors


AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15). Data as JSON: /api/errors/99fb8c7e58ca8cbf. Report an issue: GitHub.