IronFlowDocs

repeat_subworkflow

Execute one child workflow sequentially until it returns an explicit completion decision. Each iteration receives static input, a one-based iteration number, and only the state value returned by the preceding iteration.

Use this node for bounded model/tool turns, pagination, and short polling loops. It is an in-process composition primitive, not durable suspension or an exactly-once side-effect mechanism.

Parameters

flowstringrequired
Child .lua flow, resolved relative to the parent flow directory.
max_iterationspositive integerrequired
Maximum child runs before the step fails. Cannot exceed IRONFLOW_MAX_REPEAT_ITERATIONS.
inputobjectdefault parent context
Static child input mapping. A string value selects the parent key when that key exists; otherwise it remains a literal.
output_keystringdefault "repeat_result"
Namespace for the final public child context and output metadata.
state_keystringdefault "repeat_state"
Child input key containing the current carried state.
next_state_keystringdefault "repeat_next_state"
Child output key containing the state for the next iteration.
until_keystringdefault "repeat_done"
Child output key containing the required boolean completion decision.
iteration_keystringdefault "repeat_iteration"
Child input key containing the one-based iteration number.
delay_secondsnumberdefault 0
Delay after an incomplete iteration and before the next child run.
backoff_factornumberdefault 1
Delay multiplier after each wait; must be at least 1.
max_delay_secondsnumberdefault max(delay_seconds, 60)
Per-wait delay ceiling, with an absolute maximum of 3600 seconds.

state_key, next_state_key, until_key, and iteration_key must be distinct. Explicit input cannot set the latter three runtime-owned keys.

Child Contract

For every iteration the child must return a boolean under until_key:

  • true completes the node. If next_state_key is present, that value is the final state; otherwise the current state is retained.
  • false continues and requires next_state_key. Only that value is carried into the next iteration.

Other child output is not carried forward. Failed child runs, missing or non-boolean completion values, a missing next state, and exhaustion of max_iterations fail the parent step without publishing a partial successful result.

Failed-child errors include the child name, iteration, status, and the bounded, redacted unresolved task-error summary described under subworkflow error handling. Recovered errors are excluded; cancellation or missing details retain the status-only fallback. The summary arrives with the live child result, without reloading history.

All registered composition nodes are available inside the child. Parent step timeouts and cancellation remain authoritative over active child runs and inter-iteration delays.

Context Output

For output_key = "result":

KeyTypeDescription
resultobjectFinal child context with _-prefixed private keys removed.
result_stateanyFinal carried state, or null when no state was supplied.
result_iterationsintegerNumber of child runs performed.
result_completedbooleanAlways true on successful node completion.
result_flowstringChild flow name.

Iteration history is intentionally not retained.

Carried state and the final child context use full, redacted live values, not persisted inspection snapshots. IRONFLOW_MAX_TASK_OUTPUT_BYTES does not replace large state with a truncation marker between iterations. CLI/API inspection of the parent may still contain markers for large final values.

Example

Parent flow:

local flow = Flow.new("bounded_counter")

flow:step("initialize", function()
    return { initial = { value = 0 }, target = 3 }
end)

flow:step("count", nodes.repeat_subworkflow({
    flow = "counter_child.lua",
    input = {
        repeat_state = "initial",
        target = "target"
    },
    max_iterations = 5,
    output_key = "counter"
})):depends_on("initialize")

return flow

Child flow (counter_child.lua):

local flow = Flow.new("counter_child")

flow:step("advance", function(ctx)
    local current = ctx.repeat_state or { value = 0 }
    local next_state = { value = current.value + 1 }
    return {
        repeat_next_state = next_state,
        repeat_done = next_state.value >= ctx.target,
        value = next_state.value
    }
end)

return flow

The complete runnable pair is in examples/11-subworkflow/repeat_subworkflow.lua.

Operational Bounds

IRONFLOW_MAX_REPEAT_ITERATIONS defaults to 128 and must be between 1 and the compiled absolute ceiling of 1024. A node may choose a lower max_iterations, but cannot raise the process limit. The node stores only the current state and final child context; payload growth inside that state remains the workflow author's responsibility.

The inspection cap is not an execution-memory limit. Existing Lua memory/conversion limits, parent timeouts, and cancellation remain enforced; use artifact references when carried payloads would otherwise grow too large.

IronFlow documentation

Find the next step

Type a keyword to search the documentation.

↑ ↓ to move · Enter to open · Esc to close