Switch Node Guide
Overview
The Switch Node sends your workflow down one of several paths depending on a single value. You choose the value once, list the cases you care about, and connect each case to whatever should happen next.
Use a Conditional node when there are two outcomes. Use a Switch when there are three or more, or whenever you would otherwise chain several Conditional nodes together to test the same field.
Use Cases
- Severity routing: send critical findings to one path, high to another, everything else to a third
- Ownership routing: alert a different team channel depending on which business unit owns the asset
- Status handling: branch on a scan's outcome — completed, partial, failed
- Playbook selection: pick a remediation path based on vulnerability class or asset type
- Tiered response: escalate differently for internal, external, and third-party assets
- Format dispatch: send each record type to the transformation built for it
Creating a Switch Node
Basic Setup
- Drag a Switch node from the Logic section of the node palette onto your canvas
- Connect the node whose output you want to branch on into its input
- In the configuration panel, set the Subject — the value every case compares against
- Add a case for each path you need, then connect each case's handle to its own branch
The node grows a new row, and a new connection point, every time you add a case. Delete a case and its row, handle and connection go with it.
Configuration Options
Node Properties
| Property | Description |
|---|---|
| Name | A descriptive name for the node |
| Subject | JSONPath expression naming the value to test (e.g. $.severity) |
| Cases | Ordered list of branches. Checked top to bottom — the first match wins |
| Else branch | Optional fallback for "none of the above". Off by default |
Case Properties
| Property | Description |
|---|---|
| Name | Label for this branch, shown on the node and on its connection |
| Value Type | Data type for the comparison (string, number, boolean) |
| Comparison | How the subject is compared against the value |
| Value | What the subject is compared against |
Note — the subject is shared. Every case tests the same expression. If you need cases that examine different fields, use separate Conditional nodes instead.
Supported Comparison Types
| Comparison | Description | Example |
|---|---|---|
| Equals | Values are equal | $.severity = "critical" |
| Not Equals | Values are not equal | $.status != "failed" |
| Contains | Text contains this substring | $.tags contains "prod" |
| Greater Than | Numerically greater | $.cvss > 7 |
| Less Than | Numerically less | $.count < 100 |
| Regex | Matches a regular expression | $.host matches "^api-" |
| Empty | Has no value (null, empty string, array or object) | $.owner is empty |
| Not Empty | Has a value | $.owner is not empty |
Set the value type to number for greater/less than. The panel only offers comparisons that make sense for the type you pick, so an invalid combination is not reachable.
How Switch Nodes Work
When a workflow is executed:
- The Switch Node receives input from its upstream nodes and merges it into one document
- The subject JSONPath is resolved against that document
- Each case is checked in order, from top to bottom
- The first case whose comparison succeeds is selected. Later cases are not chosen, even if they would also match
- If no case matches, the else branch is selected — if the node has one
- The selected branch runs; every other branch, and everything downstream of it, is marked skipped
- The node writes the full evaluation — every case's result, not just the winner — to its output
Branch Selection Diagram
┌── Case 1 = critical ──→ Page on-call
│
Input ──→ Switch ────┼── Case 2 = high ─────→ Create ticket
$.severity │
├── Case 3 = medium ───→ Add to backlog
│
└── Else (optional) ────→ Log only
Exactly one path runs. Every other path — and everything
downstream of it — is marked skipped.
Order matters
Because the first match wins, ordering your cases from most specific to most general is the difference between a working switch and a confusing one.
A case using contains "crit" placed above one using = "critical" will swallow it — the broader case matches first and the narrower one never runs. The panel numbers each case and provides up/down arrows so you can rearrange them; reordering never disturbs your existing connections, because each branch keeps its own identity and the wires follow the case rather than the position.
The else branch
The else branch is off by default. Turn it on when you want a path for "none of the above" — it runs whenever none of the cases match, and it is where you handle a value you did not anticipate.
Left off, an unmatched value simply stops there. The node still finishes successfully — this is not treated as an error — and every branch is marked skipped.
Turning the else off removes its connection along with its handle. That is deliberate: a connection pointing at a branch the node can no longer choose would sit on the canvas looking live while never running.
Rejoining Branches
If several branches should feed back into one shared node — a common notification or reporting step — enable continue on error on the last node of each branch.
That flag is what stops the skip from spreading past those nodes, so the shared node downstream still runs. Put it on the branch endpoints, not on the shared node itself: the node carrying the flag is the one that gets sacrificed, so flagging the shared node would sacrifice the very thing you are trying to reach.
┌── Case 1 ──→ Handler A ⚑ ──┐
│ │
Switch ─────┼── Case 2 ──→ Handler B ⚑ ──┼──→ Notify team
│ │
└── Else ────→ Fallback ⚑ ──┘
⚑ = continue on error enabled
The flag goes on the branch endpoints, never on the shared node.
The shared node receives the successful branch's output plus a short error document from each branch that did not run. A Scripting Agent is the usual way to handle that mix — it can read the branch that produced real data and ignore the rest.
Example Configurations
Example 1: Severity routing
Three severity bands plus a fallback.
{
"switch_subject": "$.finding.severity",
"switch_cases": [
{
"id": "a1b2c3d4",
"label": "Critical",
"comparison_type": "equals",
"right_value": "critical",
"value_type": "string"
},
{
"id": "e5f6a7b8",
"label": "High",
"comparison_type": "equals",
"right_value": "high",
"value_type": "string"
},
{
"id": "c9d0e1f2",
"label": "Medium",
"comparison_type": "equals",
"right_value": "medium",
"value_type": "string"
}
],
"switch_has_else": true
}
Input data:
{
"finding": {
"id": "F-1042",
"severity": "high",
"asset": "api-gateway-prod"
}
}
The High branch runs. Critical, Medium and the else branch are all skipped.
Example 2: Numeric banding
Score bands, ordered from narrowest to widest. Note that Critical must come first — a score of 95 satisfies both cases, and only the first is selected.
{
"switch_subject": "$.risk.score",
"switch_cases": [
{
"id": "b3c4d5e6",
"label": "Critical",
"comparison_type": "greater_than",
"right_value": "90",
"value_type": "number"
},
{
"id": "f7a8b9c0",
"label": "Elevated",
"comparison_type": "greater_than",
"right_value": "60",
"value_type": "number"
}
],
"switch_has_else": true
}
Example 3: Presence check with no fallback
Routes assets that have an owner recorded, and deliberately stops for those that do not.
{
"switch_subject": "$.asset.owner",
"switch_cases": [
{
"id": "d1e2f3a4",
"label": "Has owner",
"comparison_type": "not_empty",
"right_value": "",
"value_type": "string"
}
],
"switch_has_else": false
}
With no else branch and no owner on the asset, the node completes and its single branch is skipped. Nothing downstream runs, and the workflow finishes normally.
Best Practices
-
Name cases after what they mean. "Critical", "Needs review" and "Unknown vendor" read far better on the canvas than the values they test. The name is what appears on the node and on the connection.
-
Put the narrowest case first. First match wins, so a broad
containsabove a preciseequalswill shadow it. -
Add an else branch when the input is not fully under your control. Data from an external API can grow new values without warning; the else branch is where you notice.
-
Leave the else off when unmatched values genuinely should stop. Silence is a valid outcome, and it is clearer than routing everything into a node that discards it.
-
Check the Output tab after a run. The node records every case's result, not just the winner, so you can see exactly why a branch was chosen — or why none was.
-
Prefer one Switch over chained Conditionals when every test looks at the same field. It is easier to read, and the ordering is explicit rather than implied by nesting.
Troubleshooting
| Issue | Resolution |
|---|---|
| The wrong branch ran | Check case order — the first match wins. A broader case above a narrower one will shadow it |
| No branch ran at all | Either no case matched and there is no else branch, or the subject did not resolve. Check the Output tab for each case's result |
| Subject not resolving | Verify the JSONPath exists in the upstream output, and check for typos. An unresolvable subject is treated as absent, not as an error |
| A numeric comparison behaves like text | Set the case's value type to number. Greater/less than require it |
| A connected node is always skipped | Confirm its case still exists. Deleting a case removes its connection; a node left connected to nothing will never run |
| Everything downstream of the switch is skipped | Expected when no case matched and the else branch is off. Add an else branch if that is not what you intended |
| Branches that rejoin never reach the shared node | Enable continue on error on the last node of each branch, not on the shared node |
Working with Edge Types
Each case owns its own connection point on the node, and so does the else branch. Connect from a case's handle to the node that should run when that case is selected.
Only one connection is ever followed per execution. Everything reached through the other cases is marked skipped, which is what makes the branches mutually exclusive rather than parallel.
Two cases may point at the same downstream node — "route both Critical and High to the escalation handler" is a supported pattern, and the handler runs when either case is selected.
Next Steps
After configuring your Switch Node, you might want to:
- Give each branch its own processing path, then rejoin them at a shared notification step
- Use a Script or Scripting Agent node upstream to normalise the value you switch on
- Combine a Switch with a Loop node to route each item in a list individually
- Chain a Conditional node inside a branch when one path needs a further yes/no decision
See Also
- Conditional Node Guide — two-way branching
- Loop Node Guide — repeating a section of the workflow
- Node Dependencies and Continue on Error — how skipping propagates, and how to rejoin branches
Updated: 2026-08-06