Flow control
Flow-control nodes shape the path through your workflow, they don't transform data, they decide what runs next.
If
What: Routes data to a true or false output port based on a condition (or set of conditions combined with AND/OR).
Inputs: Any.
Outputs: true, false. Items that matched the condition leave via true; the rest leave via false.
Configuration:
| Field | Notes |
|---|---|
| Conditions | A list. Each condition is value1 operator value2. |
| Combinator | and (all must match) or or (at least one). |
Operators: equal, notEqual, greaterThan, lessThan, greaterThanOrEqual, lessThanOrEqual, contains, notContains, startsWith, notStartsWith, endsWith, notEndsWith, regex, isEmpty, isNotEmpty, isNull, isNotNull, isTrue, isFalse.
Example: "Is the order amount over $1000?"
value1: {{ $trigger.body.amount }}
operator: greaterThan
value2: 1000Connect true to a high-value-order branch; connect false to the normal path.
๐ธ Screenshot needed:
flow-control__if-config.png, If node inspector with one condition configured and both output ports labelled on the canvas.
Switch
What: Multi-way branching. Routes to a named output port based on which case matches.
Inputs: Any.
Outputs: One per case (case1, case2, โฆ, default).
Configuration: A list of cases. Each case has an expression to match plus a label that becomes the output port name. The default port catches anything that didn't match.
Example: "Route by event type."
case1 โ eventType == "order.created" โ port: orders
case2 โ eventType == "subscription.*" โ port: subscriptions
case3 โ eventType == "refund.*" โ port: refunds
default โ port: defaultLoop
What: Iterates over a collection. The downstream chain runs once per item; after the last item, the done port fires.
Inputs: A collection (array, object, range).
Outputs: loop (one item at a time) and done (after all items).
Configuration:
| Field | Notes |
|---|---|
| Mode | array, object (key/value pairs), range (numeric), batch (groups of N), page (pagination cursors) |
| Source | Expression that resolves to the collection |
| Batch size | For batch and page modes |
| Filter | Optional expression to skip items |
| Sort | Optional field to sort by |
Pattern:
[Trigger]โโโ[List items]โโโ[Loop]โโโ
โโโโ[Process one item]โโโโฆ
โโโโ[Loop completes]โโโ[Summarise]
(loop port) (done port)The downstream node sees $node["Loop"].json as the current item.
๐ธ Screenshot needed:
flow-control__loop-config.png, Loop node inspector inarraymode with the source expression pointing to$node["List items"].json.items.
Merge
What: Combines two or more incoming streams into one.
Inputs: Any number, on the single input port (multiple connections allowed).
Outputs: output, items from each input, optionally combined per row.
Configuration:
| Field | Notes |
|---|---|
| Mode | append (concatenate), merge by index, merge by key (join on a shared field), multiplex (cartesian product) |
| Key field | For merge by key |
Use when: Recombining the true and false branches of an If, or joining results from parallel branches.
Delay
What: Pauses the workflow for a fixed (or computed) duration.
Inputs: Any.
Outputs: output, the same data, after the delay.
Configuration:
| Field | Notes |
|---|---|
| Duration | Milliseconds, or expression returning ms |
| Strategy | fixed or exponential backoff (for retries) |
Use when: Rate-limiting yourself against a flaky downstream API; staggering bulk operations; waiting for an external system to catch up.
Approval
What: Pauses execution and awaits a human decision. The workflow status becomes waitingForInput. The approval surfaces in /approvals (and optionally via email / Slack notifications).
Inputs: Data to review.
Outputs: approved and rejected.
Configuration:
| Field | Notes |
|---|---|
| Title | What the approver sees |
| Message | Long-form description |
| Data to show | Which fields from the upstream node to display |
| Approvers | One or more users / roles |
| Approval policy | Any one, All approvers, Majority |
| Timeout | Optional, what happens if nobody responds in time (reject, approve, escalate) |
| Public link | If on, generates a shareable URL for external approvers (no login required) |
See Section 08, Approvals for the full guide.
Error handling
What: Catches a thrown exception from an upstream node so the workflow can continue on a recovery path.
Inputs: Connected to the node you want to protect.
Outputs: output (success path passes through) and error (an exception was caught; error data has message, type, stack, plus original input).
Configuration:
| Field | Notes |
|---|---|
| Catch on | Which error types to catch (all, timeout, network, authentication, validation, custom regex) |
| Max retries | Retry the protected node N times before routing to error |
| Retry delay | Initial delay; combine with exponential backoff strategy |
Chain
What: Sequences dependent operations explicitly, so the runtime treats them as one logical step. Mostly cosmetic, guarantees ordering in the timeline view.
Workflow control
What: Sends control signals (pause, resume, stop) to other workflow runs. Advanced.
Split
What: Splits a single array input into one item per outgoing branch. Like Loop but with parallel branches instead of sequential iteration.
Tips & gotchas
- If vs Switch: If is binary; Switch supports many cases. For 3+ branches, Switch is cleaner.
- Loop state is persisted. A workflow can pause mid-loop (e.g. an approval at iteration 47) and resume exactly where it stopped.
- Merge
by keyneeds a unique key field in every input stream, otherwise rows silently overwrite each other. - Delays consume execution time against your workflow timeout. A 10-minute delay on a 5-minute-timeout workflow will fail. Bump the timeout in workflow settings.
- Error handling doesn't catch every failure mode. Workflow-level failures (invalid expression, missing required field) bypass it. It only catches exceptions thrown during a node's execution.
Related
Found something out of date? This page lives in the Flero docs content set.