> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.ovalbee.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.ovalbee.com/_mcp/server.

# Router

> Send the flow down the branches whose rules a value holds. Every rule that holds runs its edges. When none holds, the Otherwise edges run, or the flow stops here.

## Overview

Sends the flow down the branches whose rules one value holds. Branches whose rules don't hold do not run.

For example, train detectors on different frameworks and compare them with [Compare object detectors](/node-library/nodes/evaluate-compare-object-detectors). Wire its **Winner framework** output, such as `yolo`, into the Router and add two rules: equal to `yolo` and equal to `deim`. Each rule leads to its framework's own predict node, which takes the **Best Model ID** from the comparison. A tie leaves the framework empty, so the run goes to **Otherwise**: connect a notification there, or nothing.

```mermaid
flowchart LR
  n1["Compare object detectors"] --> n2["Router"]
  n2 -- "yolo" --> n3["Predict YOLO"]
  n2 -- "deim" --> n4["Predict DEIM"]
  n2 -- "Otherwise" --> n5["Notification"]
```

For a single yes/no check, a [Condition](/node-library/nodes/flow-control-condition) is enough. The Router is for more outcomes.

### Rules

Choose how the value is read, **Text**, **Number**, or **Yes / No**, once for the whole Router. When you wire the value from a number or yes/no output and no rule has a value yet, the editor picks the matching type for you. Each rule is one line: an operator and the value to compare with. The rules are the branches the Router can take; connect only the ones you need.

| Type     | Operators                                                                                                                                         |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| Text     | Equal to, Not equal to, One of (a list), Contains, Starts with, Is empty. Upper and lower case and spaces around the text don't matter.           |
| Number   | =, ≠, >, \<, ≥, ≤, and Between (a min, a max, or both, with both ends included). A count badge like `1,250 images` is read by its leading number. |
| Yes / No | Is true, Is false. Values like yes/no, true/false, and 1/0 work too.                                                                              |

### Edges

Each edge leaving the Router carries a chip with its rule: the value alone for an **Equal to** rule, such as `yolo`, or the condition in short, such as `≥ 1000`, or **Otherwise**. Hover the chip to pick another rule. A new edge takes the first rule that has no edge yet, then Otherwise. When rules overlap, such as `> 3` and `> 5` for a value of 7, both branches run. Connect only the rules you need: when none of the rules that hold has an edge, the run goes to **Otherwise**, like a value no rule holds. With no Otherwise edge, the flow stops at the Router.

## How it works

Reads **Value to check** as text, a number, or a yes/no.

Checks every rule and takes each one that holds.

Runs the edges of those rules; the other branches don't run. When no rule holds, runs the **Otherwise** edges, or stops the flow here if there are none.

Writes the branch it took to the **Branch** output, such as `yolo` or `Otherwise`.

## FAQ

#### What happens when the value is empty or can't be read?

No rule holds, except **Is empty**, and the run goes to **Otherwise**. The same goes for a value that doesn't fit the type, such as `abc` compared as a number. The log says why.

#### What happens to the edges when I change the rules?

Changing or reordering rules keeps every edge attached. Deleting a rule leaves its edges with a red **Pick a rule** chip, and such an edge never runs until you pick a rule for it.

## Inputs

**`Value to check`** `string` — required

Value the rules compare, usually wired from an earlier node's output such as a winner's framework, a score or a count. Key: `VALUE`.

---

**`Rules`** `branch_rules` — required, default: \{'type': 'text', 'rules': \[]}

Every rule the value holds sends the flow down its edges. Each edge leaving the Router belongs to one rule or to Otherwise. Flow variables aren't accepted. Values come from `VALUE`. Key: `RULES`.

---

## Outputs

**`Branch`** `string`

The branches the run took, comma-separated - a rule's value for an "equal to" rule, its condition otherwise - or Otherwise. Key: `BRANCH`.

---

## JSON config

Machine-readable node interface for automation and advanced usage.

#### Show JSON

```json
{
  "name": "Router",
  "description": "Send the flow down the branches whose rules a value holds. Every rule that holds runs its edges. When none holds, the Otherwise edges run, or the flow stops here.",
  "category": "Flow control",
  "namespace": null,
  "templateKey": "flow_control/router",
  "version": "v1",
  "inputs": [
    {
      "key": "VALUE",
      "label": "Value to check",
      "type": "string",
      "description": "Value the rules compare, usually wired from an earlier node's output such as a winner's framework, a score or a count.",
      "required": true,
      "default": null,
      "visibleWhen": null,
      "options": {
        "anyType": true
      }
    },
    {
      "key": "RULES",
      "label": "Rules",
      "type": "branch_rules",
      "description": "Every rule the value holds sends the flow down its edges. Each edge leaving the Router belongs to one rule or to Otherwise.",
      "required": true,
      "default": {
        "type": "text",
        "rules": []
      },
      "visibleWhen": null,
      "options": {
        "ref": "VALUE",
        "allowVariables": false
      }
    }
  ],
  "outputs": [
    {
      "key": "BRANCH",
      "label": "Branch",
      "type": "string",
      "description": "The branches the run took, comma-separated - a rule's value for an \"equal to\" rule, its condition otherwise - or Otherwise.",
      "artifact": false,
      "badge": false,
      "badgeOpens": null,
      "hidden": false
    }
  ],
  "widgets": {
    "widget": {
      "id": "variable",
      "settings": {
        "template": {
          "type": "input",
          "value": "By {VALUE}"
        }
      }
    }
  }
}
```