infiniflow/ragflow · error · ValueError
[VariableAggregator] variables of group `{g.get('group_name'
Error message
[VariableAggregator] variables of group `{g.get('group_name')}` should be a list of strings What it means
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.
Source
Thrown at agent/component/variable_aggregator.py:43
Parameters for VariableAggregator
- groups: list of dicts {"group_name": str, "variables": [variable selectors]}
"""
def __init__(self):
super().__init__()
# each group expects: {"group_name": str, "variables": List[str]}
self.groups = []
def check(self):
self.check_empty(self.groups, "[VariableAggregator] groups")
for g in self.groups:
if not g.get("group_name"):
raise ValueError("[VariableAggregator] group_name can not be empty!")
if not g.get("variables"):
raise ValueError(f"[VariableAggregator] variables of group `{g.get('group_name')}` can not be empty")
if not isinstance(g.get("variables"), list):
raise ValueError(f"[VariableAggregator] variables of group `{g.get('group_name')}` should be a list of strings")
def get_input_form(self) -> dict[str, dict]:
return {
"variables": {
"name": "Variables",
"type": "list",
}
}
class VariableAggregator(ComponentBase):
component_name = "VariableAggregator"
@timeout(int(os.environ.get("COMPONENT_EXEC_TIMEOUT", 3)))
def _invoke(self, **kwargs):
# Group mode: for each group, pick the first available variable
for group in self._param.groups:
gname = group.get("group_name")View on GitHub (pinned to 554fb1133a)
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.
Example fix
// before
{"group_name": "inputs", "variables": "begin@query"}
// after
{"group_name": "inputs", "variables": ["begin@query"]} Defensive patterns
Strategy: type-guard
Validate before calling
for g in aggregator_param.groups:
assert isinstance(g.get('variables'), list), f'group {g.get("group_name")} variables must be a list' Type guard
def variables_is_list(g: dict) -> bool:
return isinstance(g.get('variables'), list) Try / catch
try:
aggregator_param.check()
except ValueError as e:
if 'should be a list of strings' in str(e):
# wrap string selectors in a list and re-save
... Prevention
- 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.
When it happens
Trigger: "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.
Common situations: 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.
Related errors
- [VariableAggregator] group_name can not be empty!
- [VariableAggregator] variables of group `{g.get('group_name'
- {} must be an array, but its type is {}
- The input of List Operations should be an array.
- Loop Variable is not complete.
AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15).
Data as JSON: /api/errors/0e457edd52f71e77.
Report an issue: GitHub.