Skip to main content

For Each Loop

Use the For Each Loop step to repeat a sequence of actions once per item in a collection. Point the step at a SmartField that resolves to either an array or a record reference set, and AutoFlow runs the connected steps once per element, exposing the current item to those steps.

Typical use cases include:

  • Processing all lines of a document. Iterate over the lines linked to a sales header and post a webhook for each one.
  • Walking a JSON array. After a Parser step explodes a payload, loop over the resulting items to insert one record per element.
  • Fanning out external calls. Iterate over a list of customers and call an external system once per customer, with the response captured per iteration.

Configure the step​

Open the flow editor, add For Each Loop, and fill in the configuration card.

Description​

  • Purpose: Make the loop's intent clear at a glance.
  • When to fill it: Always. The description is shown in the editor and execution history.
  • Tips: Name what is being iterated, for example, For each sales line or For each charge in payload.

Selector​

  • Purpose: A SmartField selector pointing to the collection to iterate over.
  • When to fill it: Required. The selector must resolve to either a SmartKit array (for example, the items output of a Parser step) or a record reference set (for example, the lines of a parent record).
  • Tips: Use the SmartField picker (assist-edit) and paste the placeholder as-is — the selector is written in the standard {{name}} notation, exactly like every other SmartField input.

Behavior​

For Each Loop produces these outputs that downstream steps can read:

  • total — the number of items in the collection, set on the first iteration.
  • iteration — the 1-based index of the current iteration.
  • items[i] — the full collection (zero-based), captured on the first iteration so it stays stable across iterations.
  • currentItem — the item for the current iteration. It is a value when the collection holds primitive values, or a record reference when the collection holds records.

When the step runs:

  1. On the first iteration, resolves the selector. If it points to a record reference set, AutoFlow loads each RecordId; if it points to an array of values, AutoFlow stores the values directly. Either way, the count is published as total.
  2. On every iteration, populates currentItem from items[iteration - 1] and runs the steps connected to the For Each edge.
  3. When iteration < total, the step asks the engine to repeat. When iteration = total, the loop ends and the flow continues with the steps after the For Each Loop.

If the collection is empty, the loop runs zero times: the For Each edge is skipped and the flow continues with the steps after the loop. This covers the everyday case where an upstream step found nothing to hand over — a Parser whose selector matched nothing, or a Find Records step that returned no rows — so an empty result is not an error and does not need a Decision step in front of the loop.

If the selector points at something that is not a collection, the step fails with The provided selector '<selector>' does not resolve to an array or iterable reference. and the execution stops. That covers a plain output name holding a single value with content — a Parser selector that matched one scalar rather than a list, say — and a dotted path such as {{customer.linez}} whose segments do not resolve.

One case stays quiet: a plain output name — one without a dot — that does not exist at all, such as a misspelled name, reads as an empty collection and skips the loop without an error. So if a loop unexpectedly does nothing, check the spelling of the selector first: a name that is not there looks exactly like a collection with no items.

Best practices​

  • Bound the cardinality. The loop runs every connected step once per element — for a 10 000-row collection that is 10 000 step executions. Filter the source before iterating instead of inside the loop.
  • Read currentItem, not items[iteration]. currentItem already accounts for the zero-based index; using items[…] directly is fragile and makes the flow harder to read.
  • Avoid mutating the source. Modifying the records you are iterating over (Insert/Modify/Delete inside the loop body) can change the iteration count or order. Snapshot what you need first, then mutate after the loop.
  • Pair with Decision for early-exit. AutoFlow has no native break, but a Decision inside the loop body can short-circuit the work for an iteration; combine that with a Job Queue cancellation if you genuinely need to stop the loop mid-flight.