Repeat Node

Overview

The Repeat node executes a branch of nodes multiple times, either a fixed number of times or once for each item in an array. This is useful for batch processing, iterating over collections, or performing repetitive tasks.

When to Use

Use a Repeat node when you need to:

  • Process each item in an array (e.g., send email to each user)
  • Perform an action a specific number of times
  • Batch process data
  • Iterate over search results or API responses
  • Apply transformations to multiple items
  • Repeat an action until a threshold is met

Configuration

Items or Count

Number or List: Specifies how many times to repeat

  • Fixed Number: Enter a number (e.g., 5) to repeat exactly that many times
  • JSONPath to Array: Enter a JSONPath expression (e.g., $.results.fetchUsers.users) to iterate over each item in an array

Loop Body

The nodes inside the repeat branch define what happens on each iteration. You configure these by adding nodes to the repeat node’s branch in the workflow editor.

How It Works

Fixed Number Iterations

When you provide a number:

  • The loop executes that many times
  • Each iteration has access to the current index via $.results.<nodeId>.iterator.current
  • The index starts at 0

Array Iterations

When you provide a JSONPath to an array:

  • The loop executes once for each item in the array
  • Each iteration has access to:
    • Current index: $.results.<nodeId>.iterator.current
    • Current item: $.results.<nodeId>.iterator.item
  • The index starts at 0

Loop Results

The repeat node collects results from all iterations:

  • Results are stored as an array at $.results.<nodeId>
  • Each element in the array is the result from that iteration
  • You can access specific iteration results by index

Examples

Example: Fixed Number Loop

Node ID: retry Number or List: 3

Loop Body:

  • makeAPICall - Attempts to call an API
  • checkSuccess - Checks if the call succeeded

This will retry the API call up to 3 times.

Access iteration number:

$.results.retry.iterator.current

Example: Process Array Items

Node ID: processUsers Number or List: $.results.fetchUsers.users

Loop Body:

  • enrichUserData - Adds additional data to user
  • sendWelcomeEmail - Sends email to user

This processes each user in the users array.

Access current user:

$.results.processUsers.iterator.item

Access current user’s email:

$.results.processUsers.iterator.item.email

Access iteration index:

$.results.processUsers.iterator.current

Example: Batch Processing with Transformation

Node ID: transformProducts Number or List: $.results.getProducts.items

Loop Body:

  1. validateProduct - Validates product data
  2. calculatePrice - Calculates final price with tax
  3. formatForExport - Formats product for export

Results:

$.results.transformProducts
// Returns array of results from each iteration:
[
  { /* results from iteration 0 */ },
  { /* results from iteration 1 */ },
  { /* results from iteration 2 */ }
]

Example: Send Bulk Notifications

Node ID: notifyUsers Number or List: $.results.getUsersToNotify.users

Loop Body:

  1. formatMessage - Creates personalized message
  2. sendEmail - Sends email to current user

Using current item in the loop:

  • In formatMessage, access user data: $.results.notifyUsers.iterator.item.name
  • In sendEmail, access user email: $.results.notifyUsers.iterator.item.email

Example: Paginated API Calls

Node ID: fetchAllPages Number or List: 10 (max 10 pages)

Loop Body:

  1. calculateOffset - Function node that calculates: $.results.fetchAllPages.iterator.current * 100
  2. fetchPage - Calls API with offset
  3. checkHasMore - Conditional that checks if there are more pages

This fetches up to 10 pages of results, 100 items per page.

Accessing Loop Data

Iterator Object

The iterator object is available at $.results.<nodeId>.iterator:

{
  "current": 2,          // Current index (0-based)
  "item": { },           // Current item (only when iterating over array)
  "continue": true       // Internal flag
}

Current Item Fields

When iterating over an array of objects:

$.results.<nodeId>.iterator.item.fieldName

Example:

$.results.processOrders.iterator.item.orderId
$.results.processOrders.iterator.item.customer.email

Loop Results

Results from all iterations:

$.results.<nodeId>

This is an array where each element corresponds to one iteration’s results.

Best Practices

  • Limit Iterations: Set reasonable limits to avoid long-running workflows
  • Error Handling: Use onFailure paths to handle errors in iterations
  • Batch Size: For large arrays, consider processing in smaller batches
  • Access Current Item: Use $.results.<nodeId>.iterator.item to access the current element
  • Index-Based Logic: Use $.results.<nodeId>.iterator.current for index-based decisions
  • Collect Results: Design nodes to return useful data that can be collected across iterations
  • Performance: Be aware that each iteration adds to execution time

Common Patterns

Process Array with Conditional Logic

Repeat: processItems ($.results.fetchItems.items)
├─ Conditional: checkItemType
│  ├─ Choice 1: Type A → processTypeA
│  └─ Choice 2: Type B → processTypeB

Retry with Backoff

Repeat: retryOperation (3)
├─ Function: calculateDelay (current * 1000ms)
├─ makeAPICall
└─ Conditional: checkSuccess
   ├─ Success → End
   └─ Failure → Continue to next iteration

Batch Update with Progress Tracking

Repeat: updateRecords ($.results.getRecords.items)
├─ Function: logProgress
│  └─ Log "Processing {{results.updateRecords.iterator.current}} of {{results.getRecords.total}}"
├─ updateRecord
└─ Conditional: checkSuccess
   ├─ Success → markComplete
   └─ Failure → logError

Filter and Transform

Repeat: processOrders ($.results.fetchOrders.orders)
├─ Conditional: filterOrders
│  └─ Choice: Status = "pending"
│     ├─ validateOrder
│     ├─ calculateTotal
│     └─ submitForProcessing

Limitations

  • No Break: Cannot break out of a loop early (use Conditional nodes to skip processing)
  • No Nested Repeat: Cannot nest repeat nodes directly within each other
  • Memory: Very large arrays may hit memory limits
  • Timeout: Long-running loops may hit workflow execution timeouts
  • Sequential Only: Iterations execute sequentially, not in parallel (use Parallel node for concurrent execution)

Error Handling

If a node within the repeat body fails:

  • The onFailure path of that node is followed (if defined)
  • If no onFailure path is defined, the entire repeat node fails
  • Use Conditional nodes to handle errors gracefully and continue to the next iteration