For Each Loop Node

The For Each Loop iterates over a list (array) of items and executes a set of workflow steps once for each item in that list. It appears on the canvas as a block — a Start node and an End node connected by a "Loop" edge — with any number of nodes placed between them as the loop body. On each iteration, the current item from the array is made available to every node inside the loop body, so those nodes can reference, process, or act on that specific item.

The For Each Loop is one of two looping constructs available (the other being the While Loop). Use it when you know the data you need to process is a list of items and you want to perform the same sequence of steps on every item.


When to Use

Use a For Each Loop when your workflow needs to:

  • Process every line item in an order — check stock, calculate tax, and update inventory for each product.
  • Send individual notifications to a list of users returned by an API call — one email or Slack message per user.
  • Create separate tickets or records for each entry in a list — for example, creating a ServiceNow incident for each failing server returned by a monitoring API.
  • Transform and write back data for each row in a table — read a list from an external system, apply business logic to each entry, and push the updated entries back.
  • Run an approval or review step for each item in a collection, where each item may be approved or rejected independently.
  • Process paginated API results where each page returns an array of records that all need the same set of downstream actions.

How It Appears on the Canvas

When you add a For Each Loop to a workflow, two nodes are created automatically:

NodeRole
For Each (Start)The controller. Holds the configuration (which array to loop over, max iterations, terminate on failure). Has four handles: Loop Enter, Loop Exit, Loop Start, Loop End.
For Each (End)The return point. When execution reaches this node, it routes back to the Start node for the next iteration.

A "Loop" edge is automatically created from the End node back to the Start node. You place the steps you want to repeat (Action Nodes, Update Data Nodes, Decision Nodes, etc.) between the Start and End nodes, connecting them in sequence.

The Start node has two outward handles:

  • Loop Start — leads into the loop body. Execution follows this path on each iteration while there are items remaining.
  • Loop Exit — leads out of the loop. Execution follows this path when all items have been processed, when the maximum iteration count is reached, or when the loop is terminated due to a failure.

Configuration

Array Data (Source List)

The core configuration is telling the loop which array to iterate over.

SettingDescription
Array pathA Data Center expression pointing to the list you want to process. This is typically the output of an upstream Action Node, Function Node, or Mapper Node — for example, nodes.fetchEmployees.executionData.data.employees. The path must resolve to a valid array at runtime.
Display nameA human-readable label shown on the canvas and in the Data Center browser.

When you select the array path in the builder, the system validates that the selected field is actually of type array. If it is not, the configuration is rejected. The array's structure (its inner fields) is automatically inspected, and the inner fields are registered in the Data Center so that nodes inside the loop body can reference them.

Max Iterations

A safety limit that prevents the loop from running indefinitely.

SettingDefaultRangeDescription
Max Iterations1001 – 500The maximum number of times the loop will iterate, regardless of the array length. If the array has 1,000 items but max iterations is 100, only the first 100 items are processed.

If your array has fewer items than the max iteration limit, the loop simply exits when all items have been processed.

Terminate on Failure

Controls what happens when a node inside the loop body fails during an iteration.

SettingDefaultBehavior
Terminate on FailureOff (false)When off, a failure in one iteration does not stop subsequent iterations. The loop continues processing remaining items.
When on, a failure in any iteration causes the loop to exit immediately. Execution proceeds to the Loop Exit path instead of continuing to the next item.

This is useful for scenarios where processing is all-or-nothing — if one item fails, there's no point continuing with the rest (e.g., a financial batch where partial processing is unacceptable).


How It Works at Runtime

Here is the step-by-step execution flow:

1. Workflow reaches the Start node. The loop index begins at 0.

2. Start node evaluates termination conditions. Before processing an item, the Start node checks:

  • Is this the End variant? (If so, route back to Start for the next iteration.)
  • Has the current index exceeded maxIterations? → Exit the loop.
  • Has terminateCurrentLoop been flagged by the execution engine (due to a failure with Terminate on Failure enabled)? → Exit the loop.

3. Start node resolves the array. The configured array path is resolved against the Data Center using a template parser. For example, {{nodes.fetchOrders.executionData.data.orders}} is replaced with the actual array of order objects.

4. Start node checks array bounds. If the resolved value is not a valid array, is empty, or has fewer items than the current index, the loop exits via the Loop Exit handle.

5. Current item is extracted. The item at position [currentIndex - 1] in the array is pulled out and placed into the execution state as response.data. This makes it accessible to all nodes in the loop body via the Data Center — typically at a path like nodes.<forEachNodeId>.executionData.data.

6. Loop metadata is updated. The Data Center is updated with:

  • executionDetails.index — the current 1-based iteration number.
  • executionDetails.isFirst1 if this is the first iteration, 0 otherwise.

7. Execution enters the loop body via the Loop Start handle. All nodes between Start and End execute in their normal order, operating on the current item's data.

8. Execution reaches the End node. The End node completes and routes back to the Start node with the loop index incremented.

9. Steps 2–8 repeat until one of the exit conditions is met. Then the workflow continues from the Loop Exit handle to whatever node comes after the loop.


Accessing the Current Item Inside the Loop

Every node inside the loop body can reference the current iteration's item through the Data Center. The typical path structure is:

nodes.<forEachNodeId>.executionData.data

This gives you the full object for the current item. If the source array is a list of employee objects like [{ "name": "Alice", "department": "Engineering" }, { "name": "Bob", "department": "Sales" }], then during iteration 1, nodes.<forEachNodeId>.executionData.data.name resolves to "Alice", and during iteration 2 it resolves to "Bob".

Additionally, you can reference the loop's metadata:

PathDescription
nodes.<forEachNodeId>.executionDetails.indexThe current iteration number (1-based).
nodes.<forEachNodeId>.executionDetails.isFirst1 on the first iteration, 0 on all subsequent iterations.

This metadata is useful for conditional logic inside the loop — for example, a Decision Node that only triggers a summary notification on the first iteration.


Per-Iteration Data Scoping

Each iteration gets its own isolated execution context. This means:

  • Node outputs are scoped per iteration. If an Action Node inside the loop calls an API and gets a response, that response is stored under the current iteration's context. It does not overwrite or interfere with the same node's output from previous iterations.
  • The Data Center nests inner node data under the loop's Start node. The system uses a blockExecutionId to track which iteration an execution belongs to, and a loopIndex to identify the iteration number. This ensures complete separation between iterations.
  • All iteration data is persisted. The full array and per-iteration execution data are saved for auditing, debugging, and progress tracking.

Progress Path

The For Each Loop appears in the progress tracker with iterations grouped together for clarity.

Grouping: All executions within a single run of the loop are grouped under a parent entry labeled with the loop's name. Within that group, individual iterations are labeled "Iteration 1", "Iteration 2", "Iteration 3", and so on. Each iteration shows the nodes that executed during that pass.

Display fields for the Start node:

StatusDisplayed Fields
DefaultTriggered at

Since the For Each Start node is a control node (not a user-facing step), the progress path display is minimal. The real value is in the grouped iteration view, which gives visibility into what happened during each pass through the loop.

Visibility settings:

SettingDescription
HideCompletely hides the loop from the progress tracker.
Hide if SkippedHides the loop only if it was skipped during execution.

Validation Rules

The workflow builder validates For Each Loop nodes at publish time using a specialized loop validation strategy.

Start node:

  • Must have exactly 2 incoming edges — one from the preceding node (Loop Enter) and one from the End node (Loop End / loopback).
  • Must have exactly 2 outgoing edges — one into the loop body (Loop Start) and one exiting the loop (Loop Exit).
  • Must not be abandoned (zero edges on both sides).
  • Source and destination handles must match the expected loop handles.

End node:

  • Must have exactly 1 incoming edge (from the last node in the loop body).
  • Must have exactly 1 outgoing edge (the loopback to the Start node).
  • Must not be abandoned.

Array path validation (on save):

  • The configured array path must point to a field that exists in the Data Center and has a data type of array. If the path is missing, invalid, or points to a non-array field, the save is rejected with a validation error.

Max iterations:

  • Must be an integer between 1 and 500.

For Each Loop vs. Mapper Node

Both the For Each Loop and the Mapper Node operate on arrays, but they serve different purposes:

AspectFor Each LoopMapper Node
PurposeExecute a full sequence of workflow steps (actions, approvals, decisions, etc.) for each item.Transform the structure of an array — rename fields, extract values, apply functions — in a single step.
ExecutionMulti-step. Each iteration can include API calls, human tasks, delays, and sub-decisions.Single-step. Produces a new array with the same number of items in a different shape.
Use whenEach item needs its own workflow — calling APIs, updating systems, waiting for approvals.You need to reshape data from one format to another before passing it to the next step.
OutputPer-iteration execution records with individual node outputs.A single transformed array.

A common pattern is to use a Mapper Node to clean or restructure an array, and then pass the result into a For Each Loop for per-item processing.


Best Practices

  • Set max iterations thoughtfully. The default of 100 is a reasonable starting point, but adjust it based on your data. If you know your lists will never exceed 50 items, set max iterations to 50 to provide a tighter safety net. If you're processing large batches, you can go up to 500.
  • Enable Terminate on Failure for all-or-nothing operations. If partial processing is dangerous or meaningless (e.g., a financial reconciliation batch), turn this on so the loop stops at the first failure rather than continuing to process remaining items.
  • Keep the loop body focused. A loop that runs 200 iterations with 10 nodes in the body creates 2,000 node executions. Keep the body lean — move data preparation outside the loop (use a Mapper Node upstream) and keep only the per-item logic inside.
  • Use the isFirst flag for one-time setup. If you need to perform an action only on the first iteration (like creating a summary record that subsequent iterations update), use a Decision Node inside the loop that checks executionDetails.isFirst.
  • Prefer Mapper Nodes for pure data transformation. If all you need is to reshape an array (rename fields, extract values), use a Mapper Node instead of a For Each Loop. It's a single step, faster, and produces cleaner Data Center output.
  • Reference the current item correctly. Always use nodes.<forEachNodeId>.executionData.data to access the current iteration's item. Don't reference the raw source array directly — that doesn't change between iterations.
  • Place the array source upstream. The array the loop iterates over must already exist in the Data Center before the loop starts. Ensure the Action, Function, or Mapper Node that produces the array is connected upstream of the For Each Start node.
  • Monitor long loops in the progress path. For loops with many iterations, the grouped progress path view ("Iteration 1", "Iteration 2", etc.) provides full visibility. Use the progress path filter to quickly find failed iterations if something goes wrong.