{"record":{"id":"0e457edd52f71e77","repo":"infiniflow/ragflow","slug":"variableaggregator-variables-of-group-g-get-g-0e457e","errorCode":null,"errorMessage":"[VariableAggregator] variables of group `{g.get('group_name')}` should be a list of strings","messagePattern":"\\[VariableAggregator\\] variables of group `(.+?)` should be a list of strings","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/component/variable_aggregator.py","lineNumber":43,"sourceCode":"    Parameters for VariableAggregator\n\n    - groups: list of dicts {\"group_name\": str, \"variables\": [variable selectors]}\n    \"\"\"\n\n    def __init__(self):\n        super().__init__()\n        # each group expects: {\"group_name\": str, \"variables\": List[str]}\n        self.groups = []\n\n    def check(self):\n        self.check_empty(self.groups, \"[VariableAggregator] groups\")\n        for g in self.groups:\n            if not g.get(\"group_name\"):\n                raise ValueError(\"[VariableAggregator] group_name can not be empty!\")\n            if not g.get(\"variables\"):\n                raise ValueError(f\"[VariableAggregator] variables of group `{g.get('group_name')}` can not be empty\")\n            if not isinstance(g.get(\"variables\"), list):\n                raise ValueError(f\"[VariableAggregator] variables of group `{g.get('group_name')}` should be a list of strings\")\n\n    def get_input_form(self) -> dict[str, dict]:\n        return {\n            \"variables\": {\n                \"name\": \"Variables\",\n                \"type\": \"list\",\n            }\n        }\n\n\nclass VariableAggregator(ComponentBase):\n    component_name = \"VariableAggregator\"\n\n    @timeout(int(os.environ.get(\"COMPONENT_EXEC_TIMEOUT\", 3)))\n    def _invoke(self, **kwargs):\n        # Group mode: for each group, pick the first available variable\n        for group in self._param.groups:\n            gname = group.get(\"group_name\")","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/agent/component/variable_aggregator.py#L25-L61","documentation":"ValueError from VariableAggregatorParam.check(): the group's 'variables' value is present and truthy but is not a Python list (e.g. a string or dict). The aggregator requires a list of variable-selector strings.","triggerScenarios":"\"variables\": \"begin@query\" (a bare string instead of a one-element list), or an object/map form. Note this check is isinstance-only; a list containing non-strings would still pass here and fail later during resolution.","commonSituations":"Hand-writing DSL and shortcutting a single selector as a string; converting configs from a format where variables were a comma-separated string; template migration artifacts.","solutions":["Wrap selectors in a list: \"variables\": [\"begin@query\"].","Split comma-separated strings into arrays when converting legacy configs.","Validate with isinstance(g['variables'], list) in any script that generates the canvas JSON."],"exampleFix":"// before\n{\"group_name\": \"inputs\", \"variables\": \"begin@query\"}\n\n// after\n{\"group_name\": \"inputs\", \"variables\": [\"begin@query\"]}","handlingStrategy":"type-guard","validationCode":"for g in aggregator_param.groups:\n    assert isinstance(g.get('variables'), list), f'group {g.get(\"group_name\")} variables must be a list'","typeGuard":"def variables_is_list(g: dict) -> bool:\n    return isinstance(g.get('variables'), list)","tryCatchPattern":"try:\n    aggregator_param.check()\nexcept ValueError as e:\n    if 'should be a list of strings' in str(e):\n        # wrap string selectors in a list and re-save\n        ...","preventionTips":["Always emit variables as a JSON array of selector strings.","Convert comma-separated selector strings to lists during migrations.","Assert isinstance(..., list) in canvas-generation code."],"tags":["variable-aggregator","type-mismatch","configuration","agent-canvas"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}