agenthub · switch-case
Route on one value across many branches. Each case label you add becomes its own output port; anything unmatched leaves through default.
Why the node earns its place
The sibling of Condition, and the clean way to fan a status field — an onboarding stage, a ticket state — to one branch per value. Chaining Conditions to do the same thing would trip the executor's no-reconverge constraint almost immediately.
Matching is equality only, deliberately: loose enough that a config "5" matches an integer 5, with an optional normalize pass. There is no expression language to learn, and no eval to audit.
How it works at run time
value input, then value_context_key from run context, then the value path into data.lower for case-insensitive, phone10 for numbers.default.What you wire
Configuration
| Key | Type | Default & options | What it does |
|---|---|---|---|
| value | string | — | Match value as a dotted path into the input `data` (e.g. 'record.stage'). Overridden by a wired `value` input or value_context_key. When `value` input IS wired, this path navigates within that wired value. |
| value_context_key | string | — | Read the match value from run context instead of data (e.g. 'stage'). Wins over the `value` path. |
| cases * | array | — | The case labels to match against, in priority order (first match wins). Each label becomes an output branch of the same name; unmatched values fall through to `default`. |
| normalize | string | default "none" none · trim · lower · phone10 | Normalize the value AND every case label before matching. lower = case-insensitive; phone10 = last 10 digits. |
What usually goes wrong
Watch for this
Case labels become port names, so they must be unique, and none of them may be called next or matched — both are keys in the node's own return envelope. Renaming a case rewires the canvas, because the label is the port.
Behaviour & provenance