Traversal
Execution begins at the root node. For each node reached, the engine runs the node’s operation, then picks the next node by following its outgoing connections. A node is never run twice in a single run. When there are no more reachable nodes to visit, the run finishes. Unlike the Data Engine’s graph model - where reaching an end node terminates evaluation and returns a value - a flow has no single “output” in the same sense. A flow finishes when its graph is exhausted. The run’s result is captured in the token’s persisted assigns and in the logs.Branching with FlowSwitch
The FlowSwitch node directs execution down one of several alternative paths based on a value computed by an inner graph. Each branch out of the switch is labelled; when the switch runs, the inner graph emits a branch name, and only the matching branch is followed. The other branches are pruned from the traversal and their nodes do not run. This is how a flow reacts to conditions - “if the employee is new, create them in the target system, otherwise update the existing record” becomes a switch with two branches.Looping with FlowEach
The FlowEach node iterates a list, running its loop body once for each element. The loop body is not a separate, independently-rooted graph - it is the continuation of the main graph from the FlowEach node’s loop port. Because the same token is threaded through every iteration, assigns written inside the loop carry forward rather than reset: the values left in the assigns by the last iteration survive into the main graph after the loop finishes. To collect a value from every iteration instead of keeping only the last, append to a list assign as the loop runs - that is what Flow Assign Append is for. When every element has been visited, execution continues past the FlowEach node along its normal output.Error handling
When a step run by a FlowAction fails, what happens next is controlled by the action’s on error policy:- halt_flow (default): the whole run aborts. No further nodes are executed and the FlowRun is finalised with status
aborted. - halt_branch: only meaningful inside a loop body - the part of the graph reached from a FlowEach loop port. It stops the current iteration and lets the loop continue with the next element, rather than failing the whole run. Outside a loop there is no surrounding iteration to move on to, so it has nothing to act on.
- continue: the error is cleared and downstream nodes run as if nothing happened.
Aborting a flow
A flow can also abort itself through a non-recoverable signal on the token. When that signal is set, the run unwinds regardless of whichon_error policy is configured on surrounding nodes - no outer action can swallow it. This is distinct from cancellation (which is user-initiated from the editor) and from the halt_flow policy (which is one action’s response to a specific error).
In practice, most flows rely on halt_flow as the default failure mode and use halt_branch or continue only where the flow’s design explicitly calls for them.