infiniflow/ragflow · error · ValueError

[Switch] 'To' can not be empty!

Error message

[Switch] 'To' can not be empty!

What it means

ValueError from SwitchParam.check(), raised during canvas validation before execution. Every condition in the Switch component must have a non-empty 'to' field naming the destination component for that branch; an empty destination makes the branch unroutable.

Source

Thrown at agent/component/switch.py:49

        super().__init__()
        """
        {
            "logical_operator" : "and | or"
            "items" : [
                            {"cpn_id": "categorize:0", "operator": "contains", "value": ""},
                            {"cpn_id": "categorize:0", "operator": "contains", "value": ""},...],
            "to": ""
        }
        """
        self.conditions = []
        self.end_cpn_ids = []
        self.operators = ["contains", "not contains", "start with", "end with", "empty", "not empty", "=", "≠", ">", "<", "≥", "≤"]

    def check(self):
        self.check_empty(self.conditions, "[Switch] conditions")
        for cond in self.conditions:
            if not cond["to"]:
                raise ValueError("[Switch] 'To' can not be empty!")
        self.check_empty(self.end_cpn_ids, "[Switch] the ELSE/Other destination can not be empty.")

    def get_input_form(self) -> dict[str, dict]:
        return {"urls": {"name": "URLs", "type": "line"}}


class Switch(ComponentBase, ABC):
    component_name = "Switch"

    @timeout(int(os.environ.get("COMPONENT_EXEC_TIMEOUT", 3)))
    def _invoke(self, **kwargs):
        if self.check_if_canceled("Switch processing"):
            return

        for cond in self._param.conditions:
            if self.check_if_canceled("Switch processing"):
                return

View on GitHub (pinned to 554fb1133a)

Solutions

  1. Open the Switch component and assign a target component for every condition branch.
  2. Remove orphaned conditions whose downstream components were deleted.
  3. Run canvas validation (check) before execution so this surfaces at save time, not run time.

Example fix

// before
{"conditions": [{"cpn_id": "switch:0", "operator": "contains", "value": "yes", "to": ""}]}

// after
{"conditions": [{"cpn_id": "switch:0", "operator": "contains", "value": "yes", "to": "answer:1"}]}
Defensive patterns

Strategy: validation

Validate before calling

for cond in switch_param.conditions:
    assert cond.get('to'), f'Switch condition missing destination: {cond}'

Type guard

def switch_condition_routable(cond: dict) -> bool:
    return bool(cond.get('to'))

Try / catch

try:
    switch_param.check()
except ValueError as e:
    if "'To' can not be empty" in str(e):
        # wire the branch target or delete the condition
        ...

Prevention

When it happens

Trigger: A Switch condition created in the canvas but with its 'To' target not yet selected; the target component deleted after the condition was configured, leaving an empty string; hand-edited DSL with "to": "".

Common situations: Building a Switch and testing before wiring all branches; refactoring the graph and removing a downstream component that conditions pointed to; importing a template whose component IDs don't match the local canvas.

Related errors


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