All nodes/Logic & Flow/Iteration
For each
Iterates over the array from the 'Array' input, one element at a time. For each element it runs the body between the 'Item' output and the 'End of pass' input. The value arriving at 'End of pass' is not read, so the node is for actions, not for building a new array (Map does that).
Type in the graph: for_each
ExecSubgraph
An error output can be enabled 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 (Item) opens the loop
body, end (End of pass) 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). |
End of passend | Execute + Dataexecute_data | — | Marks the end of one pass of the body. The value that arrives is not read. |
Outputs
| Port | Wire | Payload | Notes |
|---|---|---|---|
Done · number of passescompleted | 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» = yes |
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.