forEach with data.findBySpec() expands duplicate steps causing cyclic dependency error
Opened by swampadmin · 11/18/2024
Description
When using forEach with data.findBySpec() in a workflow, the step expansion produces duplicate steps for each version of a data entry, not just the latest version. This causes duplicate step names which triggers a "Cyclic dependency detected" error at runtime.
Steps to Reproduce
- Create a
@k8s/servicemodel instance and run itslistmethod a few times (producing multiple data versions per service) - Create a workflow with a forEach step that iterates over the data:
steps:
- name: endpoints-${{ self.svc.attributes.name }}
forEach:
item: svc
in: ${{ data.findBySpec("my-services", "service") }}
task:
type: model_method
modelIdOrName: my-services
methodName: getEndpoints
inputs:
serviceName: ${{ self.svc.attributes.name }}- Evaluate the workflow:
swamp workflow evaluate my-workflow --input '...' --json - Observe that each service appears N times (once per data version) instead of once
For example, with 3 services and ~3 versions each, the evaluated workflow produces 9 getEndpoints steps instead of 3, with triplicate step names like:
endpoints-frontend(×3)endpoints-backend-svc(×3)endpoints-database-svc(×3)
- Run with
--last-evaluated:swamp workflow run my-workflow --last-evaluated --json - Error:
{"error": "Workflow execution failed: Cyclic dependency detected: "}
Expected Behavior
data.findBySpec(modelName, specName) should return only the latest version of each data entry when used in a forEach context, producing one step per unique data instance.
Actual Behavior
It returns all versions of all data entries matching the spec, causing duplicate forEach expansions and duplicate step names.
Environment
- swamp version: 20260226.174314.0-sha.0a12c9ff
- OS: macOS (Darwin 22.6.0)
- Shell: zsh
Summary
This bug affects the workflow evaluation service's forEach expansion when data.findBySpec() returns multiple versions of the same data entry. The fix would involve either deduplicating data entries by name (keeping only the latest version) during forEach expansion, or having data.findBySpec() default to returning only the latest version of each entry.
Closed
No activity in this phase yet.
Sign in to post a ripple.