infiniflow/ragflow · error · ValueError
Invalid logical operator,should be 'and' or 'or'.
Error message
Invalid logical operator,should be 'and' or 'or'.
What it means
ValueError from LoopItem.end(): after evaluating all termination conditions, the results are combined with all() when logical_operator=='and' or any() when 'or'; any other value (including empty/None or a typo like 'AND') makes should_end None and raises.
Source
Thrown at agent/component/loopitem.py:146
logical_operator = parent._param.logical_operator if hasattr(parent._param, "logical_operator") else "and"
conditions = []
for item in parent._param.loop_termination_condition:
if not item.get("variable") or not item.get("operator"):
raise ValueError("Loop condition is incomplete.")
var = self._canvas.get_variable_value(item["variable"])
operator = item["operator"]
input_mode = item.get("input_mode", "constant")
if input_mode == "variable":
value = self._canvas.get_variable_value(item.get("value", ""))
elif input_mode == "constant":
value = item.get("value", "")
else:
raise ValueError("Invalid input mode.")
conditions.append(self.evaluate_condition(var, operator, value))
should_end = all(conditions) if logical_operator == "and" else any(conditions) if logical_operator == "or" else None
if should_end is None:
raise ValueError("Invalid logical operator,should be 'and' or 'or'.")
if should_end:
self._idx = -1
return True
return False
def next(self):
if self._idx == -1:
self._idx = 0
else:
self._idx += 1
if self._idx >= len(self._items):
self._idx = -1
return False
def thoughts(self) -> str:
return "Next turn..."View on GitHub (pinned to 554fb1133a)
Solutions
- Set the Loop component's logical operator to exactly 'and' or 'or' (lowercase) in the UI.
- If editing JSON, add/fix "logical_operator": "and" on the Loop component's parameters.
- Re-save the Loop component from the editor so the current schema writes the canonical value.
Example fix
// before "logical_operator": "AND" // after "logical_operator": "and"
Defensive patterns
Strategy: validation
Validate before calling
logical_operator = getattr(loop_param, 'logical_operator', 'and') or 'and'
assert logical_operator in {'and', 'or'}, logical_operator Type guard
def is_valid_logical_operator(op) -> bool:
return op in ('and', 'or') Try / catch
try:
loop_item.end()
except ValueError as e:
if 'Invalid logical operator' in str(e):
# set logical_operator to 'and'/'or' and re-run
... Prevention
- Always set logical_operator to exactly 'and' or 'or'.
- When generating canvas JSON, default the field rather than omitting it.
- Re-save older Loop components after schema changes.
When it happens
Trigger: The parent Loop's logical_operator attribute is missing, empty, or not exactly 'and'/'or' (e.g. 'AND', 'And', 'xor', ''). It is read from parent._param with no default normalization.
Common situations: Hand-edited canvas JSON where the key was deleted or capitalized; older templates saved before logical_operator existed; frontend writing a display label instead of the canonical token.
Related errors
- Loop Variable is not complete.
- Invalid operator: {operator}
- Loop condition is incomplete.
- Invalid input mode.
- [Switch] 'To' can not be empty!
AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15).
Data as JSON: /api/errors/8e8ea9bb62a236c2.
Report an issue: GitHub.