the path · 07
for_each fan-out — one task, many items.
run itnika try 07-for-each-locales
07-for-each-locales.nika.yaml
# SPDX-License-Identifier: Apache-2.0# yaml-language-server: $schema=https://nika.sh/spec/v1/workflow.schema.json## 07 · for_each fan-out — one task, many items.## 02 fanned out by writing three tasks. That works until the list is decided# at run time, or has fifty entries. `for_each:` is the same fan-out with the# collection as data: one task definition, one iteration per element, and a# `.output` that is the array of results in input order.## Demonstrates ·# - `for_each:` · run a task once per element of a collection# - `${{ item }}` + `${{ index }}` · loop-scoped locals, not a namespace# - `max_parallel:` · a ceiling on concurrent iterations# - `fail_fast: false` · finish the batch even when one element fails# - fan-in · the whole array lands in one downstream binding## Run · nika run examples/07-for-each-locales.nika.yamlnika: v1workflow: id: for-each-localesmodel: mock/echo # the dry twin · this file teaches the loop, not the translationspermits: {} # pure compute · no file, no host, no program (see 01)const: source: "Welcome to the launch." locales: ["fr", "es", "de", "ja", "pt"]tasks: translate: for_each: ${{ const.locales }} # five elements → five iterations max_parallel: 3 # at most 3 in flight · the rest queue # Default is fail_fast: true — the first failure cancels the siblings. # A batch job usually wants the opposite: four good translations beat # zero, and you would rather learn which one broke. fail_fast: false on_error: # Without this, a failed element fails the task even under # fail_fast: false. `recover: null` keeps the array whole and puts a # null at that index — so filter nulls at the fan-in below. recover: null with: locale: ${{ item }} # the current element n: ${{ index }} # its 0-based position infer: prompt: "Translate to locale '${{ with.locale }}' (#${{ with.n }}) · ${{ const.source }}" max_tokens: 256 collect: with: # One binding, five results. `tasks.translate.output` is the ARRAY, in # the order of `const.locales` — not the order they finished. translations: ${{ tasks.translate.output }} infer: prompt: "Combine these translations into a localization table · ${{ with.translations }}" max_tokens: 1024# Both the array and the table, so the ordering guarantee is visible · read# with `--output json`.outputs: translations: ${{ tasks.translate.output }} table: ${{ tasks.collect.output }}nika-spec@6ac29351a · sha256 aaa32bb4b1cc5709…