Skip to main content
← Back to list
01Issue
BugShippedSwamp CLIPublicTeam
Assigneesstack72

Relationships

#1347 Run-context variables (run.id, workflowRunId) undefined in step-input CEL after suspend+resume

Opened by kneel · 7/22/2026· Shipped 7/23/2026

Inside a workflow step's inputs, the run namespace (run.id, run.workflowId, …) and the flat workflowRunId variable resolve correctly on a fresh, single-pass run. But if the run suspends at a manual_approval gate and is later resumed, any step that executes after the gate fails to evaluate its input CEL:

Invalid expression: Unknown variable: run

>    1 | run.id
         ^

workflowRunId fails the same way (Unknown variable: workflowRunId). This contradicts the docs (references/workflow/references/expressions-and-foreach.md, "Workflow Run Context"), which state these variables are available "at step execution time." A resumed step is executing, yet the run context is not repopulated in its CEL evaluation scope.

Steps to reproduce

Minimal, deterministic — two workflows sharing one throwaway command/shell echo model.

  1. swamp model create command/shell repro-runid

  2. Workflow A (fresh, no gate), single step:

    inputs:
      run: "echo RUNID=${{ run.id }} WFRUNID=${{ workflowRunId }}"

    swamp workflow run repro-runid-nogateSUCCEEDS, logs RUNID=<uuid> WFRUNID=<uuid> (both resolve, equal).

  3. Workflow B (identical echo step, but gated):

    - name: gate
      task: { type: manual_approval, prompt: "...", timeout: 3600 }
    - name: echo-runid          # dependsOn gate (succeeded)
      task:
        type: model_method
        modelIdOrName: repro-runid
        methodName: execute
        inputs:
          run: "echo RUNID=${{ run.id }} WFRUNID=${{ workflowRunId }}"
    swamp workflow run repro-runid-gate           # suspends at gate
    swamp workflow approve repro-runid-gate gate
    swamp workflow resume repro-runid-gate

    FAILS on echo-runid: Step failed: "Invalid expression: Unknown variable: run\n\n> 1 | run.id\n ^"

The only difference between A and B is the suspend/resume across the approval gate.

Expected

run.id / workflowRunId resolve in step inputs on resumed runs exactly as on fresh runs. The post-resume context should be seeded with run-metadata variables — reconstructable from the run record, not "ephemeral data."

Actual

The run namespace and flat workflowRunId are undefined for any step evaluated after resume, so those references throw Unknown variable and fail the step.

Impact

Any workflow that scopes post-approval work to its own run id — a recommended pattern (the docs' own example uses run.id to prevent cross-run data collisions) — cannot use it in exactly the place it matters most: the step gated behind human approval. Real-world hit: a Stripe hourly-payout workflow's createPayout step (gated by manual approval) filtered data.query('... workflowRunId == "' + run.id + '"') and failed every resume with Unknown variable: run, blocking the payout until the run-scoping was replaced with data.latest(...).

Workaround

Source post-gate inputs from data.latest(model, name) / data.query(...) predicates that don't reference the run namespace.

Secondary — docs defect

expressions-and-foreach.md says: "The flat workflowRunId variable is also available (equivalent to run.id) for backward compatibility with data.query() predicates." This reads as if workflowRunId is a top-level CEL variable you can concatenate into a query string — but it throws Unknown variable: workflowRunId in step-input CEL (confirmed even on a fresh run, where run.id works). Docs should clarify it's only meaningful as a record field inside a data.query(...) predicate, and that neither run.* nor workflowRunId survives into a resumed step's CEL.

Environment

  • swamp 20260720.142822.0-sha.0caa5556 (git sha 0caa555)
  • Platform: linux
  • Reproduced with plain local swamp workflow run / resume (no serve, no third-party extension — command/shell echo only)
02Bog Flow
OPENTRIAGEDIN PROGRESSSHIPPED+ 1 MOREASSIGNED+ 2 MOREREVIEW+ 4 MOREPR_MERGED+ 1 MORECONTRIBUTOR_NOTIFIED

Shipped

7/23/2026, 11:41:53 PM

Click a lifecycle step above to view its details.

03Sludge Pulse
kneel moved this from the private collective Elowish to public9/1/2026, 2:59:31 AM
stack72 assigned stack727/23/2026, 10:44:18 PM
Editable. Press Enter to edit.

stack72 commented 7/23/2026, 11:42:03 PM

Thanks @kneel for reporting this! The fix has been merged and a release is on its way. We appreciate your contribution to swamp.

Sign in to post a ripple.