Switch Node
此内容尚不支持你的语言。
The switch node branches on a list of tests, checked in order. The first case whose expression is true wins, and the run follows the outgoing edge labelled with that case’s label. When no case is true, the run follows the edge labelled default, which every switch must have. It calls no language model: no tokens, no credits.
Use it instead of a chain of condition nodes when one decision has more than two outcomes (“over 1,000”, “gold customer”, “everything else”). Use a router instead when one variable already holds the name of the branch (for example an llm node that classified the message with matchAnyOf).
See Workflow Overview for the node/edge envelope this fits into.
Config fields
Section titled “Config fields”| Field | Type | Required | Description |
|---|---|---|---|
cases | array | Yes | 1 to 10 cases, tested in order. Each one is a label and an expression (fields below). |
Each entry in cases:
| Field | Type | Required | Description |
|---|---|---|---|
label | string | Yes | The name of the case and the label of the outgoing edge it routes to. At most 100 characters, no leading or trailing spaces, no line breaks. Unique within the node, ignoring letter case. Reserved labels are refused (below). |
expression | string | Yes | The test, in the same expression language as a condition node (at most 500 characters). A true result selects the case. |
Reserved labels: a case cannot be called default, true, false, success, failure, loop_exhausted, answered, unanswered, approved, rejected, expired, changes_requested, body or done (in any letter case). These are edge labels the engine gives a meaning to, now or in planned node types.
Every rule above is checked when you save or publish: a missing field, more than 10 cases, a reserved or repeated label, or an expression with a syntax error is refused with a BAD_USER_INPUT error naming the node and the field (for example cases[1].expression is not a valid expression: ...). The node also takes the common maxVisits field, like every node.
Edges: one per case, plus default
Section titled “Edges: one per case, plus default”A switch’s edges must match its cases exactly. Publishing refuses a switch unless:
- every case label has exactly one outgoing edge with that
label(the edge label must match the case label exactly, letter case included); - there is exactly one outgoing edge labelled
default; - there are no other outgoing edges: no unlabelled edge and no edge with a label that is not a case. The one exception is
loop_exhausted, which any node may carry.
Two cases (or a case and default) may point at the same node, as separate edges.
[ { "id": "e1", "source": "size", "target": "large_order", "label": "large" }, { "id": "e2", "source": "size", "target": "vip", "label": "gold" }, { "id": "e3", "source": "size", "target": "standard", "label": "default" }]Unlike a router’s defaultTarget (a node id in the config), a switch’s default is a real edge in edges.
How the cases are evaluated
Section titled “How the cases are evaluated”- Cases are tested from first to last, and testing stops at the first true one. Put the most specific test first: with
amount > 1000beforeamount > 100, an order of 5,000 takes the first case. - “True” means any truthy result, the same as a condition:
true, a non-zero number, non-empty text. - A missing variable makes that case false, it does not fail the run. If an expression names a variable this run does not hold, the case is skipped and testing continues with the next one, so a switch whose every case names missing variables takes
default. This is the same rule as a condition, and the opposite of aset_variableexpression, which fails without adefault. A variable that exists with the valuenullcounts as present. - Types are not converted. The text
"0"is not the number0, socount == 0is false whencountholds"0". Store numbers as numbers first, for example with aset_variablenode andcoerce: "number". - Any other evaluation error (for example calling something that is not a function) fails the run with an error naming the node, the case number and its label.
- An expression can only read variables. Assignment (
x = 5) and function definitions are refused when you save; see No assignment and no function definitions. - Prefer flat variable names, as in a condition. A dotted name such as
order.totalreads into a variable that holds an object; it cannot read into text, and anllmnode stores text unless it has anoutputSchema. For a structuredllmnode, setflattenand test the flat names (request_intent == "cancel_order").
When the run fails
Section titled “When the run fails”Publishing makes these impossible, but a draft test can run a graph that has not been published. If the edge for the chosen branch is missing (no default edge when nothing matched, or no edge for the case that won), the run fails at the switch: the switch’s own trace row is FAILED: it still shows what the switch chose (matchedCase), carries failurePhase: "routing", and its error names the node, the branch and the edge labels it has, a NodeFailedEvent is published, and the user gets the standard failure reply. A missing case edge never falls back to default, and the run never ends silently.
The run trace
Section titled “The run trace”The switch’s row in the run trace (workflowRuns { nodeTrace }) carries:
| Field | When | Meaning |
|---|---|---|
matchedCase | always | The label of the case that won, or default when none did. |
matchedCaseIndex | when a case won | Its position in cases, counting from 0. Absent for default. |
switchUnresolved | when a case named a missing variable | [{ index, label, variables }] for each case skipped because a variable was not set. |
Cases after the winner are never tested, so they never appear in switchUnresolved. Which case won is recorded on the trace only; it is not left in the run context for later nodes. If a later node needs it, put a set_variable node on each branch.
Switch, router or condition?
Section titled “Switch, router or condition?”| Use | When | Branches on |
|---|---|---|
condition | One yes/no question. | One expression; edges true and false. |
switch | More than two outcomes, each decided by a test on values (amount > 1000, tier == "gold"). | Up to 10 expressions in order; edge default required. |
router | One variable already holds the branch name, usually an llm classification with matchAnyOf. | The text value of one variable; defaultTarget recommended. |
Worked example: route an order by size and customer tier
Section titled “Worked example: route an order by size and customer tier”Large orders go to a manager, gold customers get a priority reply, everyone else gets the standard reply. The amount arrives as text, so a set_variable node turns it into a number first.
{ "nodes": [ { "id": "start", "type": "start", "label": "Start", "config": {}, "position": { "x": 0, "y": 0 } }, { "id": "normalise", "type": "set_variable", "label": "Amount as a number", "config": { "assignments": [ { "variable": "amount", "kind": "template", "source": "{{amountText}}", "coerce": "number" } ] }, "position": { "x": 0, "y": 100 } }, { "id": "size", "type": "switch", "label": "Order size and tier", "config": { "cases": [ { "label": "large", "expression": "amount > 1000" }, { "label": "gold", "expression": "tier == \"gold\"" } ] }, "position": { "x": 0, "y": 200 } }, { "id": "large_order", "type": "response", "label": "Manager review", "config": { "messageTemplate": "A manager will review this order today." }, "position": { "x": -200, "y": 300 } }, { "id": "vip", "type": "response", "label": "Priority reply", "config": { "messageTemplate": "Thanks for being a gold customer. Your order is on its way." }, "position": { "x": 0, "y": 300 } }, { "id": "standard", "type": "response", "label": "Standard reply", "config": { "messageTemplate": "Your order is confirmed." }, "position": { "x": 200, "y": 300 } } ], "edges": [ { "id": "e1", "source": "start", "target": "normalise" }, { "id": "e2", "source": "normalise", "target": "size" }, { "id": "e3", "source": "size", "target": "large_order", "label": "large" }, { "id": "e4", "source": "size", "target": "vip", "label": "gold" }, { "id": "e5", "source": "size", "target": "standard", "label": "default" } ]}A gold customer ordering 5,000 takes large (the first true case). A gold customer ordering 50 takes gold. A turn with no tier at all skips the gold case (it names a missing variable) and, under 1,000, takes default.
Next steps
Section titled “Next steps”- Triage a support ticket end to end — See the end-to-end example: a
switchwith ordered cases and adefaultedge, between a classifier and an approval. - Condition Node — the same expression language, for a single yes/no.
- Router Node — branch on a variable that already holds the branch name.
- Set Variable Node — turn text into numbers before a switch tests them.
- Workflow Diagnostics — non-blocking checks on a graph.
- Workflows API Reference — creating, updating and publishing workflows.