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

  1. Set the Loop component's logical operator to exactly 'and' or 'or' (lowercase) in the UI.
  2. If editing JSON, add/fix "logical_operator": "and" on the Loop component's parameters.
  3. 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

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


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