Loop block
Configure the Loop block to run steps once per item in a list, and reference the current item and index from the steps inside the loop.
The Loop block (type: "loop") runs a set of steps once for each item in a list, one item at a time, and collects the results. For the plain-language guide, see Repeat for each item or run steps side by side.
When to use it
- Create one invoice per row returned by a table or report.
- Post a reminder for each overdue invoice.
- Match each bank transaction against open invoices.
To run independent items at the same time instead, use the Parallel block with forEach.
Configuration
Field (config key) | Editor label | Type | Required | Meaning |
|---|---|---|---|---|
collection | Collection | string | Yes | A whole template reference to a list, such as {{steps.find_open.rows}}. Roots input, steps and variables are read; a steps reference needs a path after the step id. |
steps | Steps inside the loop on the canvas | string array | Yes | Ids of the steps to run for each item, in order. |
itemVariable | Not shown | string | No | Name for the current item. Default item. Cannot be loop. |
indexVariable | Not shown | string | No | Name for the current index. Default index. Cannot be loop or the same as itemVariable. |
errorStrategy | Not shown | break or continue | No | Default break: a failed item stops the loop and fails the run. continue records the failure and moves to the next item. |
breakCondition | Stop When | expression | No | Stops the loop once true, checked after each item. Uses the Condition expression forms. |
batchSize | Batch Size | number | No | 1 to 1000. Processes the list in groups of this size. |
concurrency | Not shown | number | No | Accepted (1 to 100) but the run processes items one at a time. |
A collection that resolves to an object becomes a list of { "key", "value" } entries. Anything else that is not a list becomes an empty list, and the loop body does not run.
The editor also shows Loop Type (For Each, For, While), Iterations, While Condition and Max Iterations. The saved workflow definition has no field for these: a loop always runs once per item in collection.
Reference the current item
Steps inside the loop read the item through the variables root:
| Reference | Value |
|---|---|
{{variables.item}} | The current item. Read a field with {{variables.item.amount}}. |
{{variables.index}} | The 0-based position. |
{{variables.loop.iteration}} | The 1-based position. |
{{variables.loop.isFirst}}, {{variables.loop.isLast}} | Whether this is the first or last item. |
{{variables.loop.length}} | Number of items. |
With a custom itemVariable of invoice, the item is {{variables.invoice}}. The variables exist only inside the loop.
Output
| Field | Type | Meaning |
|---|---|---|
iterations | array | One entry per item: index, item, success, output (from the last step of that item), error, durationMs, stepResults. |
successCount | number | Items that completed. |
failureCount | number | Items that failed. |
totalCount | number | Items in the list. |
skippedCount | number | Items not processed because the loop stopped early. |
wasTerminatedEarly | boolean | true when breakCondition or an error stopped the loop. |
terminationReason | string | break_condition, error or none. |
durationMs | number | Time the loop took. |
The editor's output list shows results, count, currentItem and currentIndex; the executor returns the fields above.
Example
This workflow finds draft invoices in a table and sends each one to the customer through Stripe.
{
"name": "Send draft invoices",
"trigger": { "type": "api" },
"steps": [
{
"id": "find_drafts",
"type": "data_table",
"name": "Find draft invoices",
"config": {
"operation": "find",
"tableId": "8c1f0f5e-2a4b-4c55-9a64-0d2f3e6b7a10",
"filter": { "status": "draft" },
"limit": 200
}
},
{
"id": "each_invoice",
"type": "loop",
"name": "For each draft invoice",
"config": {
"collection": "{{steps.find_drafts.rows}}",
"itemVariable": "row",
"steps": ["send_invoice", "mark_sent"],
"errorStrategy": "continue"
}
},
{
"id": "send_invoice",
"type": "action",
"name": "Send invoice in Stripe",
"action": "stripe.sendInvoice",
"config": { "invoiceId": "{{variables.row.fields.stripeInvoiceId}}" }
},
{
"id": "mark_sent",
"type": "data_table",
"name": "Mark row sent",
"config": {
"operation": "update",
"tableId": "8c1f0f5e-2a4b-4c55-9a64-0d2f3e6b7a10",
"matchKey": "stripeInvoiceId",
"matchValue": "{{variables.row.fields.stripeInvoiceId}}",
"data": { "status": "sent" }
}
}
]
}send_invoice and mark_sent appear in the top-level steps array but run only from the loop.
Errors and limits
- An invalid config, such as a missing
collectionor an emptystepslist, fails the step withInvalid loop step config. - With
errorStrategy: "break", a failed item ends the loop and the run fails withLoop execution failed with N failures. - With
errorStrategy: "continue", the loop step is recorded as failed when any item failed, and the run carries on. - A loop with no items completes with
totalCount0 and does not run the steps inside it. - There is no iteration cap at run time. Bound a large list before the loop, for example with the Data Table
limit.
Loopfour