Skip to content

foreach: is not a for_each alias — no engine expands it #475

Description

@jeremymanning

core/loop_contracts.py (merged in #473) declared foreach a supported alias of for_each, on the strength of a comment rather than a run. It is not one.

Two shapes, run through the hermetic Python API:

- id: loop
  foreach: "['A','B']"
  steps:
    - id: w
      tool: filesystem
      action: write
      parameters: {path: "out/{{ index }}.txt", content: "{{ item }}"}

YAMLCompilerError: Failed to compile pipeline: Schema validation failed: 325 errors

The same file with for_each: writes 0.txt and 1.txt containing A and B.

In a shape that does compile, the body runs once and $item/$index resolve to None — the loop never expands.

Where the spelling does appear:

  • engine/pipeline_spec.py:72 converts a foreach field into a LoopSpec, for the declarative engine only.
  • compiler/control_flow_compiler.py:119 — the principal compiler — branches on for_each only, and _create_for_each_task reads only that spelling.

So the two engines disagree, and the validator was siding with the one that does not run the pipeline. #479 removes foreach from the loop contracts so validation stops reporting it as a working construct.

The remaining decision is whether foreach should be implemented in the control-flow compiler or rejected at schema level. It is currently neither: it parses and silently does nothing. Catalogue files that use it: examples/migration_showcase.yaml, examples/web_research_pipeline.yaml, examples/advanced/parallel_processing.yaml — all currently failing validation for other reasons too.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions