Skip to main content
← Back to list
01Issue
BugOpenSwamp CLIPublic
AssigneesNone

Relationships

#1780 Step-level dependsOn on a forEach step never evaluates true (except `always`)

Opened by randybias · 8/22/2026

Summary

A step whose dependsOn references a forEach step in the same job is always skipped with reason: "dependency" for succeeded, failed, completed, skipped and any and/or/not composition — even when every iteration succeeded. Only condition: { type: always } lets the dependent step run. Job-level dependsOn on the job containing the forEach works correctly.

Steps to reproduce

jobs:
  - name: main
    steps:
      - name: deploy
        forEach: { item: env, in: "${{ inputs.envs }}" }        # envs: [dev, qa]
        task:
          type: model_method
          modelType: command/shell
          modelName: fr-${{ self.env }}
          methodName: execute
          inputs: { run: echo ok-${{ self.env }} }
      - name: after
        dependsOn: [{ step: deploy, condition: { type: succeeded } }]
        task:
          type: model_method
          modelType: command/shell
          modelName: after
          methodName: execute
          inputs: { run: echo after }

swamp workflow run <wf>deploy-dev and deploy-qa both succeeded, then main │ skipped (dependency) for after; run status succeeded, after never runs. Changing the condition to always runs after.

Expected

after runs after all iterations succeed (or whatever aggregate semantics the condition implies — e.g. succeeded = all iterations succeeded, failed = any failed).

Likely cause

JobRun.replaceExpandedSteps() replaces the template StepRun (deploy) with the expanded entries (deploy-dev, deploy-qa). ExecutionService.shouldStepRun()TriggerCondition.evaluate()JobRun.getStatus("deploy") looks the template name up by exact stepName and gets undefined, so every leaf condition is false. The ordering graph is remapped to the expanded names (execution_service.ts, "Map dependencies to all expanded step names") but the condition evaluation is not aggregated.

Suggested fix

In JobRun.getStatus(ref) (or in shouldStepRun), when ref is a forEach template name, aggregate the expanded steps' statuses: succeeded iff all succeeded, failed iff any failed, skipped iff all skipped, completed iff all terminal. Add a test with a templated dependency.

Environment

swamp 20260822.011157.0-sha.06b61472, Linux x86_64, local repo, command/shell models.

02Bog Flow
OPENTRIAGEDIN PROGRESSSHIPPED

Open

8/22/2026, 7:19:27 PM

No activity in this phase yet.

03Sludge Pulse

Sign in to post a ripple.