# Loop

> Configure the Loop node, build the loop body, and read its output, with examples and fixes for common issues.

## What it does

Iterates over a collection and runs the nodes in the loop body once for each item.

## When to use the Loop

A Loop fits a collection of items to process, such as a list of records returned by an API, a list of files, or a list of IDs. The loop runs once per item and stops when the collection is exhausted.

To exit before the collection is exhausted, use **Break on condition** or a break handle, both described below.

## Configuration reference

| Field | Required | Default | Description |
|---|---|---|---|
| **Collection** | Yes | None | Array to iterate over. Enter an expression that resolves to an array, for example `$vars.listCustomers1.output`. |
| **Parallel** | No | Off | Runs all iterations at the same time instead of one after another. When off, the loop runs sequentially and waits for each iteration to finish before starting the next. |
| **Break on condition** | No | None | Expression that exits the loop early when it becomes `true` after an iteration completes. This applies to sequential loops. |
| **Show break handle** | No | Off | Adds a **break** handle to the loop so nodes inside the body can exit the loop early. Connect a node's output to the break handle to stop iterating from inside the body. Available in sequential and parallel loops. |

:::note
Sequential iteration preserves order and is required for **Break on condition** to work, since the condition is checked after each iteration completes. Parallel iterations don't run in a guaranteed order.
:::

## The loop on the canvas

The Loop appears on the canvas as a container. A badge at its top right shows the mode, **Sequential** or **Parallel**, and the **Parallel** toggle in the properties panel switches it. Inside the container, a **start** handle on the left begins each iteration and a **continue** handle on the right ends it. The **+** button inside the container adds a node to the body, and the **+** on the right edge adds the node that runs after the loop. The **continue** handle accepts edges from more than one node, so each path through the body can end at it. A **break** handle appears when **Show break handle** is on.

The Loop node supports error handling, so its **Error handling** tab can add an **Error** handle, as [Error handling](error-handling.md) describes.

## The loop body

Nodes placed inside the Loop boundary form the body. Nodes in the body can read the current item and iteration, along with any variables in scope outside the loop.

### Current item and iteration

Inside the body, reference the loop's progress with these expressions:

- `$vars.<loopName>.currentItem` is the item for the current iteration. Access its fields with dot notation, for example `$vars.loop1.currentItem.id`.
- `$vars.<loopName>.currentIteration` is the current iteration number, starting at `1`.
- `$vars.<loopName>.collection` is the full array that is being iterated.

These are available only inside the loop body.

## Output

After all iterations complete, the loop's aggregated results are available at `$vars.<loopName>.output`. The run then continues with the node after the loop.

`currentItem` and `currentIteration` are not accessible outside the loop body.

## Examples

### Example 1: Call an API for each item

The loop iterates over `$vars.listCustomers1.output`. The loop body contains an HTTP Request node with the URL:

```
https://api.example.com/customers/{{ $vars.loop1.currentItem.id }}
```

### Example 2: Build a result array across iterations

A Script node in the loop body returns a value for each item. The loop collects each iteration's result into `$vars.loop1.output`:

```javascript
return { id: $vars.loop1.currentItem.id, processed: true };
```

After the loop, `$vars.loop1.output` is an array of those results.

### Example 3: Stop early once a match is found

A Decision node in the loop body checks the current item. With **Show break handle** enabled, the Decision's matching branch connects to the loop's break handle to stop iterating as soon as the match is found.

## Common issues

### The loop body never runs

The collection is empty or `undefined`. Check the upstream node's output in the execution trace to confirm the array has items. An empty collection skips the body and continues after the loop.

### Break on condition never triggers in a parallel loop

Break on condition is evaluated after each iteration completes in order, so it applies to sequential loops. Turn off **Parallel** if you need to break on a running condition.

### Editing the collection inside the body does not change what is iterated

The collection is captured when the loop starts. Modifying the array variable inside the body doesn't change which items are iterated. This is by design.

## Next steps
- [Control flow](control-flow.md): the nodes that branch, repeat, and rejoin paths.
- [Decision](node-decision.md): branching on a condition.
- [Variables and data flow](variables-and-data-flow.md): how nodes pass data.
- [Community](community.md): ask questions and share workflows with other builders on the UiPath Forum.
