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.

For each
ArrayResult
ItemItem

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.

Entry
Template
For each
Log
Exit
  • Execute + Data
Press “Copy nodes”, open the editor and hit Ctrl+V on the canvas.

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. entry usually 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 item and an edge into end are both required, even though the value on end is unused.
  • A loop inside a loop. Nested loops are rejected by the validator. Sequence them instead (Done into the next loop’s input) or move the inner walk into code_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

PortWirePayloadNotes
ArrayinputExecute + Dataexecute_data

Run trigger and array payload (JSON array or string encoding an array).

ItemendExecute + Dataexecute_data

End of subgraph for one item; return value from inner graph.

Outputs

PortWirePayloadNotes
ResultcompletedExecute + Dataexecute_data
ItemitemExecute + Dataexecute_data

Configuration

FieldTypeDefaultDescription
Include indexinclude_indexbooleanfalse

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_variablestringitem

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.