Skip to main content
Runs a subgraph once for every item in a list. Connect the body you want to repeat to the Loop Body output port. Inside the loop, the current item is available in the configured item assign — read it with an Assign Read node (or let Attribute nodes pick it up as the subject, if it’s a defdata struct). Each iteration starts from the same assigns the loop was entered with. Values the body writes — a composed record, a list it builds, a step’s output — are scratch: they belong to that item and are gone when the next one starts. If you want something to survive, say so with Collect or Preserve below.

Configuration

  • Source list assign — assigns key holding the list to iterate.
  • Current item assign — the loop body reads the item from here.
  • Collect — optional. One row per value you want out of the loop: name the assign to collect into, and pick where the value comes from (same sources as Flow Compose). Each named assign is emptied when the loop starts and gets one entry appended per successful iteration, so the list is ready to use straight after the loop — no accumulator to reset, and it stays correct when this loop sits inside another one. “Successful” means the iteration reached the end of the loop body without failing. One that stopped early (a Flow Guard set to skip branch) or that recorded an error (a Flow Action whose step failed) contributes nothing, so the collected list holds only the items that worked. Setting the failing step’s On error to Continue does not bring it back: the error stays on the record either way. Collect is for results, not for capturing failures.
  • Preserve — optional. Name assigns the loop body builds up itself, most often a map grown by a Flow Map Put or a list grown by a Flow Assign Append. Unlike Collect, the loop never initialises them: the value carries from iteration to iteration, a loop nested inside this one keeps adding to the same value, and it is still there for the nodes after the loop. Reach for this when you want one accumulated value rather than a list with one entry per item. Put a Flow Assign before the loop if you need it to start from a known value. Because the loop never touches them, an iteration that failed keeps whatever it managed to write before it stopped — including anything written by a Flow Action’s Error port. That makes a preserved assign the place to gather notes about failures, which Collect deliberately drops.

Control flow

  • Halt branch inside an iteration (e.g. from a Flow Guard) stops that iteration but the loop continues with the next item.
  • Halt flow (from a Flow Guard set to halt flow, or any unrecoverable error) stops the whole run immediately.
  • An iteration that stops early or fails is skipped by Collect but keeps its writes to Preserved assigns. So to record something about a failure — a message, a file name, a count — write it to a preserved assign from the Flow Action’s Error port, and leave Collect for the successful results.

Tips

  • Pair with Flow Filter first to narrow the list down — iterating a filtered list is usually cheaper and clearer than guarding inside the loop body.
  • To print what the loop gathered, put a Flow Log after it and reference the assign with a format modifier — {report:lines} prints one item per line, instead of the Elixir list syntax a bare {report} renders.

Ports