Skip to main content
← Back to list
01Issue
BugClosedSwamp Club
AssigneesNone

forEach with object items and static step name causes spurious cyclic dependency error

Opened by swampadmin · 4/19/2025

Description

When a forEach iterates over an array of objects and the step name doesn't interpolate a scalar field from the item, all expanded steps get the name stepName-[object Object]. This causes the topological sort to see duplicate nodes and report a cyclic dependency, even though there is no actual cycle.

Steps to Reproduce

  1. Create a workflow with a forEach step that iterates over an array of objects
  2. Use a static step name (no ${{ self.item.field }} interpolation)
  3. Run the workflow
steps:
  - name: scan-vm
    forEach:
      item: vm
      in: ${{ data.latest('my-model', 'vms').attributes.vms }}
    task:
      type: model_method
      modelIdOrName: my-scanner
      methodName: scan
      inputs:
        namespace: ${{ self.vm.namespace }}
    dependsOn: []
    weight: 0
    allowFailure: true

The forEach.in expression returns an array of objects like [{namespace: "cicd", podName: "pod-1", vmDomain: "vm-1"}, ...].

Expected Behavior

Either:

  • Steps get unique auto-generated names (e.g., index-based suffixes: scan-vm-0, scan-vm-1, ...)
  • A validation error at swamp workflow validate time telling the user that forEach over objects requires a scalar field in the step name

Actual Behavior

All expanded steps get the name scan-vm-[object Object] because JavaScript's default object-to-string conversion is used. Since all step names are identical, the topological sort detects a spurious cycle:

FTL error Error: "Workflow execution failed: Cyclic dependency detected: "

Note the empty cycle path — there is no actual cycle, just duplicate node names.

Workaround

Include a scalar field from the forEach item in the step name:

- name: scan-${{ self.vm.vmDomain }}

Suggested Fix

The forEach expansion code in execution_service.ts (expandForEachSteps()) could:

  1. Detect when the item is an object and the expanded step name still contains [object Object], then either fall back to index-based naming or raise a clear error
  2. Add a validation rule in swamp workflow validate that checks forEach steps over object arrays include at least one ${{ self.item.field }} reference in the step name

Environment

  • swamp version: 20260304.014630.0-sha.88b753fc
  • OS: macOS Darwin 25.3.0
02Bog Flow
OPENTRIAGEDIN PROGRESSCLOSED

Closed

No activity in this phase yet.

03Sludge Pulse

Sign in to post a ripple.