{"record":{"id":"99fb8c7e58ca8cbf","repo":"infiniflow/ragflow","slug":"must-be-an-array-but-its-type-is","errorCode":null,"errorMessage":"{} must be an array, but its type is {}","messagePattern":"(.+?) must be an array, but its type is (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"agent/component/iterationitem.py","lineNumber":45,"sourceCode":"        return True\n\n\nclass IterationItem(ComponentBase, ABC):\n    component_name = \"IterationItem\"\n\n    def __init__(self, canvas, id, param: ComponentParamBase):\n        super().__init__(canvas, id, param)\n        self._idx = 0\n\n    def _invoke(self, **kwargs):\n        if self.check_if_canceled(\"IterationItem processing\"):\n            return\n\n        parent = self.get_parent()\n        arr = self._canvas.get_variable_value(parent._param.items_ref)\n        if not isinstance(arr, list):\n            self._idx = -1\n            raise Exception(parent._param.items_ref + \" must be an array, but its type is \" + str(type(arr)))\n\n        if self._idx > 0:\n            if self.check_if_canceled(\"IterationItem processing\"):\n                return\n            self.output_collation()\n\n        if self._idx >= len(arr):\n            self._idx = -1\n            return\n\n        if self.check_if_canceled(\"IterationItem processing\"):\n            return\n\n        current_item = arr[self._idx]\n        self.set_output(\"item\", current_item)\n        # Keep `result` as a compatibility alias because existing DSL examples\n        # and downstream references may still consume IterationItem via `@result`.\n        self.set_output(\"result\", current_item)","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/agent/component/iterationitem.py#L27-L63","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Make the upstream producer emit an actual array: parse JSON output in a Code component (json.loads) before feeding Iteration.","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).","If the value may legitimately be a single item, wrap it: use a Code component to return [value] when not isinstance(value, list)."],"exampleFix":"# before: LLM output (str) wired straight into Iteration items_ref\n# after: Code component normalizes to list\nimport json\ndef main(arg0):\n    v = arg0\n    if isinstance(v, str):\n        v = json.loads(v)\n    if not isinstance(v, list):\n        v = [v]\n    return v","handlingStrategy":"type-guard","validationCode":"arr = canvas.get_variable_value(items_ref)\nif not isinstance(arr, list):\n    raise SystemError(f'{items_ref} is {type(arr).__name__}, expected list')  # fail early with context","typeGuard":"def is_array(v) -> bool:\n    return isinstance(v, list)","tryCatchPattern":"try:\n    iteration_item._invoke()\nexcept Exception as e:\n    if 'must be an array' in str(e):\n        # fix upstream producer to emit a list, then re-run canvas\n        ...","preventionTips":["Parse JSON-string outputs into lists in a Code component before wiring to Iteration.","When referencing composite outputs (e.g. another Iteration's aggregate dict), select the specific list field.","Test canvases with realistic data so type mismatches surface at authoring time."],"tags":["iteration","type-mismatch","agent-canvas","variable-resolution"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}