Iteration Nodes
Martha workflows support array processing through three iteration node types: for-each, filter, and reduce. These let you iterate over search results, filter matching items, and aggregate outputs — all within the visual workflow builder.
For-Each Node
Iterates over an array, executing a body node for each item. Items are processed in configurable concurrent batches.
Configuration
| Field | Required | Default | Description |
|---|---|---|---|
source_array | Yes | — | The array to iterate over. Use a variable reference like {{steps.search.results}}. |
item_variable | No | item | Name to access the current item in templates |
concurrency | No | 5 | Max items to process in parallel per batch |
error_mode | No | collect | collect = gather all errors, fail_fast = stop on first error |
output_key | No | results | Key name for the output array |
Template Variables
Inside the for-each body, you can reference:
| Variable | Description |
|---|---|
{{foreach.item}} | The current array item |
{{foreach.index}} | The current index (0-based) |
{{foreach.<item_variable>}} | Same as {{foreach.item}} if item_variable is left as default |
Example
Process a list of documents through an LLM summarization step:
{
"type": "FOR_EACH",
"config": {
"source_array": "{{steps.search.documents}}",
"concurrency": 3,
"error_mode": "collect"
}
}Connect the for-each node to its body node using an edge with source_handle: "foreach-body". The body node receives each item and produces a result that is collected into the output array.
Error Handling
collectmode (default): All items are processed. Failed items appear as error entries in the output array. The for-each node itself succeeds.fail_fastmode: Processing stops at the first error. Already-completed items are preserved in the output.
Filter Node
Filters an array by evaluating conditions against each item. Items that match all (or any) conditions are kept.
Configuration
| Field | Required | Default | Description |
|---|---|---|---|
source_array | Yes | — | The array to filter. Use a variable reference. |
conditions | Yes | — | Array of condition objects (see below) |
match_mode | No | all | all = item must match every condition, any = item must match at least one |
output_key | No | filtered | Key name for the filtered output array |
Conditions
Each condition has three fields:
| Field | Description |
|---|---|
field | Path to the value on each item (e.g., score, metadata.category) |
operator | Comparison operator (see table below) |
value | Value to compare against (not needed for is_empty, is_not_empty, is_falsy, is_truthy) |
Operators
| Operator | Description |
|---|---|
equals | Exact match |
not_equals | Not equal |
contains | Substring or element check |
not_contains | Inverse of contains |
greater_than | Numeric > |
less_than | Numeric < |
greater_or_equal | Numeric >= |
less_or_equal | Numeric <= |
is_empty | None, "", [], {} |
is_not_empty | Inverse of is_empty |
is_falsy | Empty/zero values: null, "", 0, false, [], {} |
is_truthy | Inverse of is_falsy |
matches_regex | Regex pattern match |
starts_with | String prefix check |
Example
Keep only high-scoring results:
{
"type": "FILTER",
"config": {
"source_array": "{{steps.search.results}}",
"conditions": [
{ "field": "score", "operator": "greater_than", "value": "80" },
{ "field": "status", "operator": "not_equals", "value": "archived" }
],
"match_mode": "all"
}
}Reduce Node
Aggregates an array into a single value using one of nine operations.
Configuration
| Field | Required | Default | Description |
|---|---|---|---|
source_array | Yes | — | The array to reduce. Use a variable reference. |
operation | Yes | — | Aggregation operation (see table below) |
field | Depends | — | Field path on each item (required for sum, min, max, collect_field) |
output_key | No | result | Key name for the reduced output |
Operations
| Operation | Description | Requires field |
|---|---|---|
count | Number of items in the array | No |
sum | Sum of numeric field values | Yes |
min | Minimum numeric field value | Yes |
max | Maximum numeric field value | Yes |
first | First item in the array | No |
last | Last item in the array | No |
concat | Concatenate string field values | Yes |
collect_field | Extract a single field from all items into a new array | Yes |
flatten | Flatten nested arrays into a single array | No |
Example
Sum the scores of filtered results:
{
"type": "REDUCE",
"config": {
"source_array": "{{steps.filter.filtered}}",
"operation": "sum",
"field": "score"
}
}Combining Iteration Nodes
These nodes compose naturally with each other and with other workflow nodes:
- For-each → Filter → Reduce: Process items, keep matches, aggregate results
- Filter → For-each: Narrow down items before expensive per-item processing
- Choice → For-each: Only iterate when a condition is met
- For-each body = Sub-workflow: Each iteration runs a full child workflow
Example Pipeline
Search → For-Each (summarize each) → Filter (score > 80) → Reduce (count)This processes search results through an LLM, filters for quality, and counts the keepers.