# Switch Step

> Route a workflow to one of many named outputs, evaluated top to bottom, with a fallback for everything that matches nothing.

The **Switch** step routes a run to one of several outputs. You define ordered **routing cases**: the first case whose conditions are met sends the run down its route, and evaluation stops there.

> Dock: Flow · Returns: the case that matched

**Reach for Switch when the answer is one of several.** A ticket is a refund, a complaint or a question — not two of them. Where two things can be true at once, [Conditions](/build/action-steps/conditions) is the step, and both routes run. See [Choosing a Flow Step](/build/action-steps/routing) for the difference between the three routing steps.

Switch takes the first matching route only, and the run continues down that one.

> **Always assign the Fallback route.** It is where a run goes when no case
> matches. Without it, unmatched runs stop at the Switch and nothing downstream
> fires.
>
> The fallback sits behind the regular cases, so it needs at least one to sit
> behind: **a Switch configured with the fallback alone routes nothing.** For a
> single unconditional route, use a case with no conditions instead, since an
> empty case matches everything.

## Setting it up

The panel is the same rule builder the Conditions step uses, so a case is built the same way: pick the data, pick its type, pick an operator, give it a value.

### Add a routing case

Click **Add routing case**. New cases are added at the **bottom**, and since evaluation runs top to bottom, a new case is checked last. Reorder them if the priority is wrong.

### Build its rule

Pick the data to test, then choose its type: **Text**, **Number**, **Yes/no**, **Record**, **List**, or **Date & Time**. Then pick an operator from that type's list. The full catalogue is on the [Conditions](/build/action-steps/conditions#operators) page, and it is shared between the two steps.

Click **Rule** to add a second rule with **AND** or **OR**.

### Point the case at a step

Under **Then go to**, choose where the run continues when this case wins. Wire
the route as you build each case rather than at the end: the connection is what
anchors a case on the canvas, so a case that leads somewhere is one that stays. If the step
it should lead to does not exist yet, **Then go to** creates it for you.

### Assign the fallback

Under **Fallback**, choose where everything that matched no case should go.

> **A case with a blank rule matches everything.** That makes an empty case a
> useful catch-all when you put it last, where first-match-wins turns it into a
> default.
>
> Everywhere else, give each case data, an operator and a value before the first
> run. **All three, including the data on the left**, which you pick with the data
> button beside the field rather than typing. A rule with a value on the right and
> nothing on the left compares an empty value against it, so the case never
> matches and the run passes it by.
>
> Drawing a connection out of a Switch creates its case straight away, so check
> them if you wire the canvas before configuring it.

## Naming your outputs

Each case takes an optional output name, up to 50 characters. It is the **Output 0** field at the top of the case. The name is echoed on the case's result, so run history reads _"Enterprise leads"_ rather than _"case 2"_.

On a Switch with more than two or three cases this is the difference between a readable execution record and a puzzle.

## Capital letters matter here

> **`Active` does not match `active`.** The Switch compares text exactly as
> written, capitals included.
>
> **How matching works** is where you change that: it holds the choice of whether
> text ignores capitalisation, and whether one matching case runs or every one
> does. The [Filter](/build/action-steps/filter-items) step starts from the same
> rule, exact by default, so a comparison behaves the same way in both.

To match regardless of capitals, turn on **Ignore capitalization** under [How matching works](#how-matching-works).

## Sending to every matching branch

By default the first matching case wins and the rest are skipped. You can have the run go down **every** branch that matches instead.

That is what you want when your cases are labels rather than a choice, such as tagging an order as both _high value_ and _international_. It is not what you want when the branches are alternatives, because the work then happens more than once.

Turn on **Run every matching branch** under [How matching works](#how-matching-works).

## How matching works

**How matching works** holds two settings that apply to every case in the step.

| Setting                       | Default | What it does                                                     |
| ----------------------------- | ------- | ---------------------------------------------------------------- |
| **Ignore capitalization**     | Off     | Turn it on and `Active` matches `active`.                        |
| **Run every matching branch** | Off     | Turn it on and every case that matches runs, not only the first. |

The fallback route is skipped whenever a case matched, whichever of these is on.

Workflows imported from another platform can carry extra options across. Those stay available in a collapsed section beneath these two, so an imported Switch keeps behaving the way it did before the move.

## Choosing a routing Mode

The **Mode** setting has two values. The default one is everything described above: the cases' rules decide where the run goes.

The other ignores the rules entirely and picks a branch by number. You supply the number, counting from zero. It is there so workflows moved over from other automation tools keep working.

**For anything you build in Glow, leave Mode alone.** Rules keep the routing readable on the canvas. A number computed somewhere else does not.

## What it passes on

The Switch does not pass data along a branch: the steps after it read the same
earlier steps they always would. What it publishes is the **decision**, which is
what you want when a run went somewhere you did not expect.

Open the **Execution log** from the toolbar and expand the Switch's entry:

```
{"mode":"rules","cases":[{"blocks":[{"conditions":[
  {"data":"","value":"NEVER_MATCHES","result":false,"operator":"equals",
   "conditionType":"string"}],"blockSuccess":false}],
  "matched":false,"caseIndex":0}]}
```

Read it from the inside out. Each condition shows the two values it compared and
its `result`. A block passes when every condition in it passed. A case matches
when one of its blocks did, and `caseIndex` says which case it was, counting
from zero.

That is usually enough to settle a routing question in one look: a rule that
looks right but reads `result: false` is comparing something other than what you
meant, and the two values beside it say what.

## Examples to copy

### Route support tickets by topic

| Case         | Output name | Data                | Type | Operator      | Value          |
| ------------ | ----------- | ------------------- | ---- | ------------- | -------------- |
| 1            | `Billing`   | `{{ 2.ret.topic }}` | Text | `is equal to` | `billing`      |
| 2            | `Bugs`      | `{{ 2.ret.topic }}` | Text | `is equal to` | `bug`          |
| **Fallback** | —           | —                   | —    | —             | general triage |

Name the outputs and the run history reads "Billing" rather than "case 1".

### One webhook, several event types

| Case         | Output name | Data             | Type | Operator      | Value        |
| ------------ | ----------- | ---------------- | ---- | ------------- | ------------ |
| 1            | `PR opened` | `{{ 1.action }}` | Text | `is equal to` | `opened`     |
| 2            | `PR merged` | `{{ 1.action }}` | Text | `is equal to` | `closed`     |
| **Fallback** | —           | —                | —    | —             | a Do Nothing |

A fallback pointing at [Do Nothing](/build/action-steps/no-operation) is the deliberate way to say "ignore anything else". It also looks different from having forgotten the fallback entirely.

### Score bands, where order is the whole design

| Case         | Output name | Data                | Type   | Operator          | Value                |
| ------------ | ----------- | ------------------- | ------ | ----------------- | -------------------- |
| 1            | `Hot`       | `{{ 3.ret.score }}` | Number | `is greater than` | `80`                 |
| 2            | `Warm`      | `{{ 3.ret.score }}` | Number | `is greater than` | `50`                 |
| **Fallback** | —           | —                   | —      | —                 | the nurture sequence |

A score of 90 matches both cases. First match wins, so it goes to `Hot`. That is why the bands must run highest first. Reverse them and every hot lead lands in `Warm`.

## What's Next?

- Fire several routes at once, or use plain-language rules, with the [Conditions Step](/build/action-steps/conditions).
- Fail loudly on the fallback with the [Stop and Error step](/build/action-steps/stop-and-error).
- Merge branches back into one path using the [Do Nothing](/build/action-steps/no-operation).
