Steps
1
Retry a failed message
A retry runs the failed attempt again with exponential backoff and jitter. It is for transient faults, not for waiting. Add it in the node’s Bad input (
engine object and send what still fails to an error edge:IllegalArgumentException) is not retried unless listed in retryOn. A retry can show the same message twice, so make side effects idempotent on the message id. All keys are in Node options.2
Poll until a condition holds
LOOP_PREDICATE wraps another processor, runs it again and again, and stops when exitCondition is true or a bound is reached. It emits only the final message. This polls a status endpoint every five seconds until the body says done:exitCondition can read #iterationCount and #elapsedTimeMs. maxIterations defaults to 10 and maxDuration to PT1M; set both on purpose. failureStrategy says what a failing iteration does: ABORT (default), RETRY, SKIP or ESCALATE.3
Emit every result instead
LOOP_STREAM takes the same options but flattens every message the iterations produce into one stream, so downstream nodes work on results as they arrive. Use it to page through results or generate a series.4
Mind the time limits
A loop is one node, so the node’s idle timeout and
deadlineMs bound it. Raise timeoutSeconds for long polling. See Time limits.Verify it worked
Start a run and read it: a retried node shows its attempts in the run log, and a message that used up its attempts arrives on theerror edge with failure.attempts and failure.message (see Messages). For the loop, the run ends once exitCondition is true, or at maxIterations or maxDuration, whichever comes first.
Variations
- A loop around several nodes. A graph has no cycles. Put one round of work into its own workflow and call it with
SUB_WORKFLOW: Run a sub-workflow. - Do not retry AI calls blindly. A model may return the same wrong answer, and each retry costs tokens; see the advice in the failure model.
Related
- Handle failures for routes, budgets and join rules.
- Routing and flow reference for every loop option.