> For the complete documentation index, see [llms.txt](https://docs.rootcause.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.rootcause.ai/more-details/applications/application-modules/foreach.md).

# For Each

> Run an inline body subgraph once per row of an items dataframe.

Runs its body once per row of `items` and collects what each pass produced.

A frame module: the body is a whole flow of its own, held in `settings.body`. `concurrency` caps how many passes run at once and `onError` decides whether one bad row fails the loop or is recorded and skipped. `collectModuleId` and `collectPortId` name the port inside the body whose value is gathered into `results`. A ForEach inside a ForEach body is refused — nest a While if you need two levels.

## At a glance

|                          |                        |
| ------------------------ | ---------------------- |
| Module type              | `ForEach`              |
| Category                 | Intelligence           |
| Default tier             | `durable`              |
| Runs on                  | `reactive`, `durable`  |
| Starts a flow            | no                     |
| Holds a body             | yes                    |
| Keeps state between runs | no                     |
| Available in             | every application type |

## Parameters

### `body`

`ForEachBodyState` · required · defaults to `{"modules":[],"edges":[]}`

The flow run once per item: its own modules and edges.

### `collectModuleId`

`string` · required · defaults to `""`

The module inside the body whose port is gathered into `results`.

### `collectPortId`

`string` · required · defaults to `""`

Which of that module's ports is gathered.

### `concurrency`

`number` · required · defaults to `2`

How many passes run at once; the backend caps it at 8.

### `onError`

`"continue" | "fail"` · required · defaults to `"continue"`

Record a failed pass in `errors` and carry on, or fail the whole loop.

## Inputs

| Port    | Kind        | Required | Description                                                                                                                           |
| ------- | ----------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `on`    | `event`     | no       | Implicit on every module that does not itself start a flow: wire an event here to make this module the start of what that event runs. |
| `items` | `dataframe` | yes      | One pass per row of this frame.                                                                                                       |
| `data`  | `dataframe` | no       | A frame every pass sees unchanged, for lookups the loop should not re-read.                                                           |

## Outputs

| Port      | Kind        | Connects to           | Description                                         |
| --------- | ----------- | --------------------- | --------------------------------------------------- |
| `results` | `dataframe` | `dataframe`, `signal` | The collected port, one row per successful pass.    |
| `errors`  | `dataframe` | `dataframe`, `signal` | One row per pass that failed, with what went wrong. |

***

[← All application modules](/more-details/applications/application-modules.md)
