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

Relationships

#1727 Concurrent suspended workflow runs can't be disambiguated from 'approvals'; fresh runs should supersede matching-input suspended runs

Opened by dmc · 8/19/2026

Environment

swamp 20260725.011748.0-sha.bb2cb3ef (macOS). Manual-approval workflow (type: manual_approval step) with a downstream model_method step.

Problem

Two related gaps make manual-approval workflows hard to operate once more than one run of the same workflow is suspended at the same gate. I hit both while driving a real approval workflow and ended up with 7 indistinguishable suspended runs.

Problem 1 — approvals doesn't surface run identity, and its suggested commands are ambiguous

  • swamp workflow approvals (human output) prints neither runId nor suspendedAt — both exist only in --json — and emits an identical swamp workflow approve "<wf>" "<step>" / reject line for every pending run.
  • With more than one run suspended, approve/reject without --run fail with Multiple suspended runs found…. That error does helpfully list the run ids — but approvals, the command whose whole job is to show pending approvals, does not.
  • Net effect: from the tool's own recommended output you cannot tell which run you would be approving, and there is no hint that --run is needed until you try. Scripts that do reject "<wf>" "<step>" in a loop silently no-op once ambiguity sets in, which is how the runs piled up.

Problem 2 — a fresh run doesn't supersede prior suspended runs of the same workflow

  • Each swamp workflow run of an already-suspended workflow adds another suspended run indefinitely. This is what produced the ambiguity in Problem 1.

Proposed solution

  1. Make approvals self-sufficient for disambiguation. Print runId + suspendedAt (and ideally a one-line inputs digest) per pending run, and echo the ready-to-run --run <id> approve/reject command for each — so the listing command alone tells you exactly what to type.

  2. Supersede matching-input suspended runs on a fresh run. On a new swamp workflow run, cancel/supersede prior suspended runs of the same workflow whose resolved inputs match — same inputs = same intent, so the newer run is authoritative. This is the key scoping constraint: runs with different inputs must be left alone. Example: an apply-sieve run with mailboxRole=archive must not cancel a suspended mailboxRole=inbox run — they are independent intents. Could be default-on with an opt-out, or an explicit --supersede flag.

Alternatives considered

  • Manually reject --run <id> each stale run — works, but only after discovering the ids via the error message or --json, which is the friction this request is about.
  • Per-run output naming (${{ run.id }}) to avoid data collisions between concurrent runs — solves data safety but not the approval-disambiguation or run-pileup UX.

Reproduction

  1. Define a workflow with a manual_approval step.
  2. swamp workflow run <wf> … twice (do not approve).
  3. swamp workflow approvals → two identical entries, no run ids shown.
  4. swamp workflow approve <wf> <step>Multiple suspended runs found.
02Bog Flow
OPENTRIAGEDIN PROGRESSSHIPPED

Open

8/19/2026, 1:01:34 PM

No activity in this phase yet.

03Sludge Pulse

Sign in to post a ripple.