All nodes/Logic & Flow/Iteration
For each
Sequentially iterates over the JSON array from the ED port 'Input'. For each element it runs the subgraph between the item and end ports (like WF tool). The value on the end port is ignored; handy for side effects.
Type in the graph: for_each
ExecSubgraph
An error branch can be enabled (expose_error_output) to handle failures on their own path.
Ports can be split into separate execution and data handles.
Try it
Walking an array with the index
A template pulls the array out of the input, the loop walks it one element at a time and logs each one.
- Execute + Data
Runs as pasted
When to use it
Reach for this node when every element of an array needs something done to it and the result is not collected: a mail per address, a row per record, a message per chat. When each element has to turn into a new value, use map; when part of the array has to be kept, use filter; when the number of repetitions depends on a condition rather than on a list, use while_loop. If the body is one transformation with no service calls, a single code_javascript node is cheaper.
How it works
input (Array) carries the array and the run trigger at once. item (Start) opens the loop
body, end (End) closes it; the body is every node on a path between them. completed
(Done) fires once, after the walk.
An array here is a JSON array or a string encoding one, and elements are visited one at a
time, in order. With “Include index” off, item carries the element itself, read in the
body as {{ inputs.input }}. With the flag on it carries {<item key>: value, index: N} —
{{ inputs.input.item }} and {{ inputs.input.index }}.
Whatever arrives on end is ignored: only the pass itself matters. The node’s result is the
number of processed elements, {{ nodes.<id>.output }}. Run details show each iteration as
its own group, “Iteration 1”, “Iteration 2” and so on.
Common mistakes
- An object on the input instead of an array.
entryusually carries something like{"items": [...]}and the node fails with “expected a list”. Put a template with{{ inputs.input.items | tojson }}in front of the loop; the validator warns about this wiring in advance. - An open body. An edge out of
itemand an edge intoendare both required, even though the value onendis unused. - A loop inside a loop. Nested loops are rejected by the validator. Sequence them
instead (
Doneinto the next loop’sinput) or move the inner walk intocode_javascript. - An edge leading out of the body. Anything continuing from a body node counts as part
of the body and runs on every iteration. Continue the graph from
completed. - Reading the body’s result from outside.
{{ nodes.<body node>.output }}outside the loop holds the last iteration only. - One failed iteration stops the loop, leaving the rest unprocessed. If failures are expected, handle them inside the body with an error branch.
Inputs
| Port | Wire | Payload | Notes |
|---|---|---|---|
Arrayinput | Execute + Dataexecute_data | — | Run trigger and array payload (JSON array or string encoding an array). |
Itemend | Execute + Dataexecute_data | — | End of subgraph for one item; return value from inner graph. |
Outputs
| Port | Wire | Payload | Notes |
|---|---|---|---|
Resultcompleted | Execute + Dataexecute_data | — | |
Itemitem | Execute + Dataexecute_data | — |
Configuration
| Field | Type | Default | Description |
|---|---|---|---|
Include indexinclude_index | boolean | false | When true, each iteration passes a dict {item_key: element, index: n} on the item port. When false, the item port carries the array element value directly (no wrapper dict). |
Item keyitem_variable | string | item | Key for the current element in the payload dict (with index) on the item port. shown when include_index = true |
Shared fields
Every node has these three — the platform adds them, not the node author.
expose_error_output— When enabled, show an execution output to connect nodes that run if this step fails.split_ports_in— Show separate execution and data input handles instead of one combined port.split_ports_out— Show separate execution and data output handles instead of one combined port.