Loading

Foreach

The foreach step iterates over an array and runs its nested steps once for each item in the array.

Use the following parameters to configure a foreach step:

Parameter Required Description
name Yes Unique step identifier
type Yes Step type - must be foreach
foreach Yes A template or JSON expression that evaluates to an array
steps Yes An array of steps to run for each iteration
steps:
  - name: loopStep
    type: foreach
    foreach: <array expression>
    steps:
      # Steps to run for each item
      # Current item is available as 'foreach.item'
		
Note

Inside the loop, the current item is always available as foreach.item. You cannot customize this variable name.

The foreach field supports the following expression types:

Use {{ }} or ${{ }} syntax when the array comes from context variables such as step outputs, inputs, or constants. Both syntaxes behave identically for foreach:

foreach: "{{ steps.getData.output.items }}"
foreach: "${{ steps.getData.output.items }}"
		

Use a plain JSON array string for static arrays known at definition time:

foreach: '["item1", "item2", "item3"]'
		

Use a JSON string containing {{ }} template expressions for dynamically built arrays with a known structure:

foreach: '[{{ steps.getCount }}, {{ steps.getCount | plus: 1 }}]'
		
Note

Avoid using plain property paths without template syntax (for example, foreach: 'consts.items'). Use foreach: "{{ consts.items }}" instead.

The workflow engine automatically provides the following variables during foreach iteration. To use these variables, reference them in your step parameters with {{ }} syntax:

Variable Description
foreach.item Current item in the iteration
foreach.index Zero-based index of the current iteration
foreach.total Total number of items in the array
foreach.items Complete array being iterated over

Example:

message: "Processing {{ foreach.item.name }} ({{ foreach.index | plus: 1 }}/{{ foreach.total }})"
		

Nested foreach loops can access parent context using step references:

steps:
  - name: outer-foreach
    type: foreach
    foreach: "{{ outerItems }}"
    steps:
      - name: inner-foreach
        type: foreach
        foreach: "{{ innerItems }}"
        steps:
          - name: log-both
            type: console
            with:
              message: "Outer: {{ steps.outer-foreach.index }}, Inner: {{ foreach.index }}"
		

Template expressions support bracket notation for keys that contain dots or other special characters:

"{{ foreach.item['service.name'] }}"
		

This example searches for documents and enriches each result with metadata:

name: National Parks Enrichment
description: Enrich each park with additional data
steps:
  - name: searchAllParks
    type: elasticsearch.search
    with:
      index: national-parks-index
      size: 100
      query:
        match_all: {}

  - name: enrichEachPark
    type: foreach
    foreach: "{{ steps.searchAllParks.output.hits.hits }}"
    steps:
      - name: logProcessing
        type: console
        with:
          message: "Processing park: {{ foreach.item._source.title }}"

      - name: addMetadata
        type: elasticsearch.update
        with:
          index: national-parks-index
          id: "{{ foreach.item._id }}"
          doc:
            last_processed: "{{ execution.startedAt }}"
            workflow_run: "{{ execution.id }}"
            category_uppercase: "{{ foreach.item._source.category | upcase }}"