Skip to main content
This node is in preview. Its behavior may change in future releases.
The Loop node is a container. Drop nodes inside it and they run once for every item in an array you resolve from upstream; nodes outside the loop run once, as usual. Reach for it when an extracted document yields a variable-length list (line items, attachments, contacts) and you need to act on each entry.

How it works

  • Drag nodes inside the Loop to make them its body. The body runs once per item, in array order.
  • Inside the body, reference the current item with {{loop.payload.item}} and its position with {{loop.payload.index}} (0-based), where loop is the loop node’s name.
  • The whole loop runs as a single sub-run, not one run per item. Open it from the run detail and use the item pager to step through each item’s output.
  • Items are processed one at a time, in array order.
If an item fails. By default (Stop the loop), the first failing item stops the loop immediately and the step fails, so the remaining items do not run. Set If an item fails to Continue with remaining items to run every item regardless: a failed item leaves a null slot in {{loop.payload.results}} and an entry in {{loop.payload.errors}}, and {{loop.metadata.failedItemCount}} counts them. In this mode the loop step completes even if every item fails, so branch on failedItemCount downstream if you need to treat that as an error. See If an item fails below.
A loop’s Store writes are held per item and committed at checkpoints as the loop progresses. In Stop the loop mode, a failed item’s own writes are discarded and the items that already succeeded stay written. A Store node reading inside the same loop sees only already-committed entries, never the loop’s own pending writes.

What can go inside

A loop body may only contain these node types:
  • Transform
  • Validation
  • Store
  • Variable
  • HTTP
  • Callback
  • Business Central (in any operation)
  • QuickBooks (in any operation)
Extract, Review, Filter, Split, Classify, Reconcile, Merge, Download, Prompt, Email, Wait, Call Workflow, Forward, If, Switch, and nested Loops are not allowed inside a loop. Place those before or after the loop instead. A body node cannot use its own error-output port or continue-on-fail: inside a loop, whether a failing item stops the loop is controlled entirely by the loop’s own If an item fails setting.

Connecting nodes

  • Connect the node that produces the array to the Loop (an edge into the loop node).
  • Connect downstream nodes from the Loop, not from a node inside it. Edges may not cross the loop boundary.
  • The Loop’s output cannot be wired to a node inside its own body: body nodes receive each item from the Loop automatically, and the Loop’s result exists only after the loop finishes. Nor can a body node be wired back to the Loop.
  • The Loop’s own outgoing connection is optional. Because the body does the per-item work, a Loop may end a branch (like a Store node in Set mode). Its source handle stays, so you can still wire it onward to downstream nodes when you need results after the loop.
  • Wire body nodes to each other inside the loop as normal. For a given item, each body node can read the previous body node’s output for that same item.

Referencing items

Inside the body, per item:
  • {{loop.payload.item}} for the current item
  • {{loop.payload.index}} for its 0-based position
  • {{loop.metadata.itemCount}} for the total number of items
After the loop, from downstream nodes:
  • {{loop.payload.results}} for the full resolved array (a failed item’s slot is null when If an item fails is set to Continue with remaining items)
  • {{loop.payload.errors}} for the list of item failures (empty on full success)
  • {{loop.metadata.itemCount}} for the count
  • {{loop.metadata.failedItemCount}} for how many items failed (0 on full success)
(Replace loop with your loop node’s actual name.)
Inside an HTTP, Callback, Business Central, or QuickBooks body: a $each row template’s own row-expansion tokens, the bare {{$item}} and {{$index}}, still refer to the $each array element, not the loop item. Every other field in the body (the URL, headers, or any body field outside a $each row) must use the qualified {{loop.payload.item}} / {{loop.payload.index}}; a bare {{$item}} or {{$index}} there resolves to nothing.

Configuration

If an item fails

  • Stop the loop (default): the first failing item stops the loop immediately, the step fails, and its error output fires. The remaining items do not run.
  • Continue with remaining items: every item runs regardless of earlier failures. A failed item leaves a null slot in {{loop.payload.results}}, an entry in {{loop.payload.errors}} (which item, which node, and the error message), and counts toward {{loop.metadata.failedItemCount}}. The loop step completes once every item has run, even when every item failed or the source array was empty. To treat too many failures as an error, add an If node after the loop that branches on {{loop.metadata.failedItemCount}}.
A body node cannot opt out of this with its own error-output port or continue-on-fail: those controls do not appear on nodes inside a loop body, because the loop’s own If an item fails setting is the only partial-failure control for the body.

Retries and checkpoints

A loop’s body runs as a resumable unit: if the run is interrupted (for example a worker restart), the loop resumes from where it left off rather than starting over, up to 3 attempts. Progress is checkpointed periodically (every 25 items, or every 60 seconds, whichever comes first): items that already completed at the last checkpoint are not rerun.
  • Store writes made by items already checkpointed stay written; a failed item’s own writes are never persisted.
  • HTTP, Callback, and Business Central and QuickBooks writes made inside a loop body each carry a unique per-item key, so if the loop resumes and reruns an item whose request already went out, the destination (for connectors) or your own endpoint (for HTTP, if it honors the idempotency header) does not receive it twice. If you set your own Idempotency-Key header on such a node, the loop appends the item index to it so every item still gets a distinct key.
  • Transient failures (a timeout, a connection error, or a 5xx/429 response) from an HTTP or connector body node are retried for that one item before the item counts as failed, using the node’s own retry settings (default 3 attempts). Only after those attempts are exhausted does If an item fails decide what happens next.
Practical budget. A loop must complete at least 25 items within an hour to make progress; a loop that consistently cannot finish 25 items in an hour never converges. If your body does slow per-item work (a slow external call, for example), keep the array small or speed up the body.

Limits

A single loop may iterate over at most 500 items. A larger source array fails the step with a clear error rather than attempting it. Filter or page the array upstream so the loop runs over fewer items.

Errors

  • Source expression is required: the Source field is empty.
  • Source expression resolved to a non-array value: the expression resolved to something other than a JSON array (an object, a string, and so on). Check the upstream output and the path you reference.
  • Loop has no body nodes: the loop is empty. Drag at least one node inside it.
  • A node cannot be inside a Loop: a body node is of a type the loop does not allow (see What can go inside).
  • An edge crosses the loop boundary: a node inside the loop is connected directly to one outside it. Connect to the Loop itself instead.
  • The item count exceeds the maximum: the run fails with “Loop … resolved N items, which exceeds the maximum of 500. Reduce the source array (for example filter or page it) so the loop runs over fewer items.”

Monitoring

The loop step shows a N failed badge and the list of item errors whenever If an item fails is set to Continue with remaining items and at least one item failed. A body node’s per-item pager marks failed items and shows each one’s error. See Monitoring runs.