While Loop Step

Repeat a block of steps as long as a condition remains true.

What it does

  • Evaluates a condition before each iteration and runs the inner steps only when it is true.
  • Exits the loop automatically the moment the condition becomes false.
  • Exposes a loop counter (loop.index, zero-based) inside each iteration so you can track progress, build offsets, or enforce a maximum number of cycles.
  • Passes the outputs of the previous iteration into the next one, letting you accumulate state across cycles (for example, a running page cursor or a collected list).

When to use it

  • When you need to iterate without a fixed list: the number of repetitions depends on runtime state, not on an array size.
  • When you need to paginate through an external API one page at a time until there are no more pages.
  • When you need to retry an operation a limited number of times until it succeeds or a maximum is reached.
  • When a downstream process is eventually consistent and you must poll until a status changes.

Split vs. While Loop: Use Split when you already have an array and want to process each element. Use While Loop when the stopping point is determined by a condition that changes as the loop runs.

How to configure

1. Loop Condition

Define the boolean expression that controls whether another iteration runs.

  • Build the condition using references to mapped values: input data (data.*), previous-step outputs (steps.<stepId>.outputs.*), loop outputs from the previous iteration (loop.outputs.*), or the built-in counter (loop.index).
  • Supports the same operators as the Conditional step: EQ, AND, OR, IS_EMPTY, etc.
  • The condition is evaluated before the inner steps run. If it is false on the very first check, the loop body never executes.

Common patterns:

  • loop.outputs.hasNextPage = true — continue while the previous iteration signaled there are more pages.
  • loop.index < 5 — run at most five iterations.
  • loop.outputs.status != "completed" — keep polling until a job finishes.

2. Inner Steps (Loop Body)

Add the steps that should run on every iteration inside the loop.

  • Use loop.index to calculate offsets or page numbers (for example, page = loop.index + 1).
  • Use loop.outputs.* to read values produced by the previous iteration (for example, the next-page cursor returned by the last API call).
  • Make sure at least one inner step updates the values the condition depends on, otherwise the loop will run forever.

3. Loop Outputs

At the end of each iteration, define what values the loop should carry forward into the next cycle.

  • Map values from inner step outputs into named loop output fields.
  • These fields become available as loop.outputs.* in both the condition and the next iteration’s steps.
  • After the loop finishes, the final iteration’s outputs are also accessible from downstream steps as steps.<whileLoopStepId>.outputs.*.

4. Maximum Iterations (Safety Limit)

Set an upper bound on the number of cycles to prevent runaway loops.

  • If the limit is reached before the condition becomes false, the step fails with a timeout/limit error.
  • Always set this to a value that reflects the realistic upper bound for your use case (for example, 50 for paginated product sync, 5 for a retry pattern).

Practical examples

Paginated API sync (Shopify products)

Goal: fetch all products from Shopify, 50 at a time, until there are no more pages.

  • Condition: loop.outputs.hasNextPage EQ true
  • Initial state (before loop starts): manually set hasNextPage = true, cursor = null
  • Inner steps:
    1. Call Shopify Products API with limit=50 and after = loop.outputs.cursor
    2. Process the returned products (upsert to your system, apply transformations, etc.)
    3. Extract pageInfo.hasNextPage and pageInfo.endCursor from the API response
  • Loop outputs:
    • hasNextPagesteps.fetch_products.outputs.pageInfo.hasNextPage
    • cursorsteps.fetch_products.outputs.pageInfo.endCursor
  • Maximum iterations: 50 (cap at 2 500 products per run; schedule another run for larger catalogs)

Typical patterns

  • Paginated syncs: iterate through Shopify products, orders, or customers page by page using a cursor or offset.
  • Polling for job completion: check a long-running job status every cycle until it is "done" or "failed".
  • Retry logic: retry a flaky external call a fixed number of times, then fail fast if all attempts are exhausted.
  • Accumulating results: collect records from multiple API calls into a running list, passing it forward via loop.outputs.

Common mistakes to avoid

  • Infinite loop: forgetting to update the condition variable inside the loop body. Always verify that at least one inner step changes what the condition checks.
  • No safety limit: leaving Maximum Iterations unset or too high. Set a realistic cap that matches your data volume.
  • Using While Loop instead of Split: if you already have a complete list, use Split—it is simpler and makes intent clearer.
  • Reading stale data: inside the loop, reference loop.outputs.* (previous iteration) not steps.<innerStep>.outputs.* from an earlier iteration—each iteration only sees its own step outputs unless you forward them through loop outputs.