While Loop Node
The While Loop repeatedly executes a set of workflow steps as long as a configured condition evaluates to true. Unlike the For Each Loop, which iterates over a list of items, the While Loop is condition-driven — it keeps running until the condition becomes false, the maximum iteration limit is reached, or a failure terminates the loop. It appears on the canvas as a block with a Start node and an End node, just like the For Each Loop.
Use a While Loop when the number of repetitions is unknown in advance and depends on a dynamic condition that changes as the workflow runs.
When to Use
Use a While Loop when your workflow needs to:
- Poll an external system at intervals until a status changes — for example, checking a third-party API every iteration until the response status moves from "Processing" to "Completed" or "Failed."
- Retry a failing operation with updated parameters — keep calling an API with different inputs until it returns a successful response.
- Process a queue-like structure where each iteration consumes an item and the loop continues while items remain — useful when the data isn't a simple array but a paginated or streaming resource.
- Wait for a human action to complete — loop until an approval status or a form field reaches a specific value.
- Run a calculation iteratively until convergence — for example, repeatedly adjusting a value until it meets a threshold defined elsewhere in the workflow.
- Implement countdown or counter-based logic — decrement or increment a global constant on each pass and exit when it hits a target.
How It Appears on the Canvas
When you add a While Loop, two nodes are created automatically:
| Node | Role |
|---|---|
| While (Start) | The controller. Holds the condition, max iterations, and terminate-on-failure settings. Has four handles: Loop Enter, Loop Exit, Loop Start, Loop End. |
| While (End) | The return point. When execution reaches this node, it routes back to the Start node to re-evaluate the condition 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 between the Start and End nodes.
The Start node has two outward handles:
- Loop Start — leads into the loop body. Execution follows this path when the condition evaluates to true.
- Loop Exit — leads out of the loop. Execution follows this path when the condition evaluates to false, max iterations is reached, or the loop is terminated by a failure.
Configuration
Condition
The core configuration is the boolean condition that controls whether the loop continues or exits. The condition is built using a rule builder, the same one used in Decision Nodes.
Condition structure:
A condition consists of one or more rule groups combined with a logical combinator (AND or OR). Each rule group itself contains individual rules, also combined with AND or OR.
Each individual rule has three parts:
| Part | Description |
|---|---|
| Operand (Field) | The value to evaluate. This is a Data Center field — it can be a form field, a global constant, a node output, or any other data available in the workflow at that point. Selected via the Data Center browser. |
| Operator | The comparison to perform. Available operators depend on the operand's data type (see table below). |
| Value | The value to compare against. This can be a static value you type in, or another Data Center field (enabling dynamic comparisons like "while field A is greater than field B"). |
Available operators by data type:
| Data Type | Operators |
|---|---|
| String | Contains, Does not Contain, Equals (case sensitive), Equals (non case sensitive), Not Equals, Is Null, Is not Null, Is Empty, Is not Empty |
| Number | Less than, Greater than, Equal to, Not equal to, Less than or equals, Greater than or equals, Is Null, Is not Null, Is Empty, Is not Empty |
| Date | Before, After, Before or Equals, After or Equals, Equals, Not Equals, Is Null, Is not Null, Is Empty, Is not Empty |
| Select | Is any of, Neither of |
| Boolean | Equals, Not Equals |
Combining rules:
Rules within a group are combined with AND or OR. Rule groups at the top level are also combined with AND or OR. This gives you the flexibility to build complex conditions like: "While (status equals 'Processing' AND retry count is less than 5) OR (override flag equals true)."
Dynamic resolution:
Both the operand and the value are resolved at runtime against the Data Center. If you reference nodes.checkStatus.executionData.data.status as the operand, the system reads the actual current value of that field each time the loop evaluates. This means the condition can change from true to false as nodes inside the loop body update the data — which is the fundamental mechanism for eventually exiting the loop.
Max Iterations
A safety limit that prevents the loop from running indefinitely.
| Setting | Default | Range | Description |
|---|---|---|---|
| Max Iterations | 100 | 1 – 500 | The maximum number of times the loop will iterate, regardless of whether the condition is still true. When the limit is reached, the loop exits via the Loop Exit handle. |
This is critical for While Loops because, unlike For Each Loops (which are bounded by the length of an array), a While Loop with a condition that never becomes false would run forever without this safeguard.
Terminate on Failure
Controls what happens when a node inside the loop body fails during an iteration.
| Setting | Default | Behavior |
|---|---|---|
| Terminate on Failure | Off (false) | When off, a failure in one iteration does not stop subsequent iterations. The loop continues evaluating the condition and processing further iterations. |
| When on, a failure in any iteration causes the loop to exit immediately. Execution proceeds to the Loop Exit path instead of re-evaluating the condition. |
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 checks for the End variant. If this is the End node (execution has completed a pass through the loop body), it simply completes and routes back to the Start node for the next evaluation.
3. Start node evaluates termination conditions. Before evaluating the condition, it checks:
- Has the current index exceeded
maxIterations? → Exit the loop via Loop Exit. - Has
terminateCurrentLoopbeen flagged by the execution engine (due to a failure with Terminate on Failure enabled)? → Exit the loop via Loop Exit.
4. Loop metadata is updated. The Data Center is updated with:
executionDetails.index— the current 1-based iteration number.executionDetails.isFirst—1if this is the first iteration,0otherwise.
5. Condition is resolved and evaluated. The system:
- Takes a deep copy of the configured condition expression.
- Uses the
ConditionHelperServiceto resolve all dynamic references in the condition against the current Data Center state. Each operand and value that references a Data Center field is replaced with its actual current value using theTemplateParserService. - Passes the fully resolved condition to the
BoolExpressionGraph.evaluatemethod, which returnstrueorfalse.
6. Routing based on result:
- If the condition is true → execution enters the loop body via the Loop Start handle. All nodes between Start and End execute in their normal order.
- If the condition is false → execution exits the loop via the Loop Exit handle. The failed condition (with both the original and resolved values) is recorded for debugging.
7. Execution reaches the End node. The End node completes and routes back to the Start node with the loop index incremented.
8. Steps 2–7 repeat until the condition evaluates to false, the max iteration limit is reached, or the loop is terminated by a failure.
Data Center Output
The While Loop exposes different fields depending on whether you're referencing it from inside the loop body or from a node after the loop.
Inside the loop (available to nodes in the loop body):
| Path | Display Name | Description |
|---|---|---|
executionDetails.index | Current Index | The current 1-based iteration number. |
executionDetails.isFirst | Is First | 1 on the first iteration, 0 on all subsequent iterations. |
After the loop (available to nodes downstream of the Loop Exit):
| Path | Display Name | Description |
|---|---|---|
executionDetails.index | Max Index | The final iteration number when the loop exited. |
executionDetails.status | Status | The execution status of the loop node. |
executionDetails.completedAt | Executed On | The timestamp when the loop finished. |
executionDetails.completedAtTimezone | Executed On Timezone | The timezone of the completion timestamp. |
Unlike the For Each Loop, the While Loop does not produce a response.data per iteration because it does not iterate over an array. The loop body nodes are responsible for fetching or computing whatever data they need on each pass.
Per-Iteration Data Scoping
Each iteration gets its own isolated execution context, identical to how the For Each Loop works:
- Node outputs inside the loop body are scoped per iteration using a
blockExecutionIdandloopIndex. - Inner node data is nested under the loop's Start node in the Data Center, ensuring iterations don't interfere with each other.
- All per-iteration execution data is persisted for auditing and debugging.
Progress Path
The While Loop appears in the progress tracker with iterations grouped together, using the same display format as the For Each Loop.
Grouping: All executions within a single run of the loop are grouped under a parent entry. Within that group, individual iterations are labeled "Iteration 1", "Iteration 2", "Iteration 3", and so on.
Display fields for the Start node:
| Status | Displayed Fields |
|---|---|
| Default | Triggered at |
Visibility settings:
| Setting | Description |
|---|---|
| Hide | Completely hides the loop from the progress tracker. |
| Hide if Skipped | Hides the loop only if it was skipped during execution. |
Retriggering
The While Loop is eligible for retriggering. If an iteration fails or stalls (status ACTION_FAILED or STALLED), an administrator can retrigger the While node. The retrigger flow:
- Clears execution records for downstream nodes.
- Re-enqueues the While Start node for processing.
- The Start node re-evaluates the condition against the current Data Center state and either continues the loop or exits, depending on the result.
This is particularly useful for long-running polling loops where an external system was temporarily unavailable.
Validation Rules
The While Loop shares the same loop validation strategy as the For Each Loop.
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.
Max iterations:
- Must be an integer between 1 and 500.
Condition:
- The condition is stored as a mixed-type schema field and is not strictly validated at the schema level beyond the Joi validation of the overall node. However, if no condition is configured, the loop will evaluate
undefinedas falsy and exit immediately on the first iteration.
While Loop vs. For Each Loop
| Aspect | While Loop | For Each Loop |
|---|---|---|
| Driven by | A boolean condition that is re-evaluated each iteration. | An array of items — one iteration per item. |
| Number of iterations | Unknown in advance. Depends on when the condition becomes false. | Known in advance (equals the array length, up to max iterations). |
| Current item data | No automatic current item. Nodes in the body must fetch their own data. | The current array item is automatically exposed via response.data. |
| Typical use cases | Polling, retrying, waiting for state changes, counter-based logic. | Processing lists: line items, user lists, records from an API. |
| Exit trigger | Condition evaluates to false, max iterations reached, or failure termination. | Array exhausted, max iterations reached, or failure termination. |
| Data Center output (inside loop) | index and isFirst only. | index, isFirst, and the current array item. |
| Data Center output (after loop) | Max Index, Status, Executed On, Executed On Timezone. | No specific external config (uses default). |
Best Practices
- Ensure the condition will eventually become false. This is the most important consideration. If the condition never changes, the loop runs until max iterations and then exits — which may waste processing time and produce confusing results. Make sure at least one node inside the loop body modifies the data the condition checks.
- Set max iterations as a meaningful safety net. The default of 100 is reasonable for most polling scenarios. For a loop that checks an external status every iteration, consider how many iterations represent an unreasonable wait (e.g., if each iteration takes 5 minutes, 100 iterations = ~8 hours). Set the limit to match your SLA.
- Use Update Data or Function Nodes to change the condition's inputs. A common pattern: an Action Node calls an external API, an Update Data Node writes the response status to a form field or global constant, and the While condition checks that field. Each iteration, the Action re-fetches and the Update Node overwrites, so eventually the condition flips.
- Enable Terminate on Failure for critical operations. If a failure inside the loop means the entire operation should stop (e.g., a financial transaction that can't proceed with partial data), turn this on.
- Use
isFirstfor initialization logic. If the first iteration needs to set up state that subsequent iterations use (like creating a tracking record), add a Decision Node inside the loop body that checksexecutionDetails.isFirst. - Combine with Delay Nodes for polling patterns. If you're polling an external system, place a Delay Node inside the loop body to add a wait between iterations. Without it, the loop runs as fast as the system can process, which may overwhelm the external service or violate rate limits.
- Keep the loop body focused. Every node inside the loop runs on every iteration. Move setup and teardown logic outside the loop to avoid unnecessary repeated execution.
- Use the external config after the loop exits. Downstream nodes can reference
executionDetails.index(Max Index) to see how many iterations ran, which is useful for reporting or conditional logic after the loop.
Updated 20 days ago
