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

Relationships

#3962 swamp serve on a v3 datastore never settles a workflow run left running by a stopped instance: boot reaper skips it as belonging to a remote instance

Opened by zack · 10/26/2026

Summary

Found while triaging #3958. On a format 3 (v3) datastore, a workflow run left running by a stopped swamp serve is never settled by serve in another checkout, and a quick restart of the same checkout does not settle it either. A v3 serve keeps its control plane in the checkout (swamp-club#3534), so it writes no heartbeats to the bucket, and the boot reaper has nothing to judge another instance's run by.

Environment

  • swamp 20261026.014016.0-sha.7e1aad04 (Linux x86_64), @swamp/s3-datastore 2026.10.24.2, --format 3, the local fake S3 from #3958. No AWS.

Reproduction

Leave a run running in the replica: the clean shutdown with a slow bucket from the companion issue. Then do either of these:

  1. Second checkout. Start serve in a copy of the repo without .swamp/ and with a fresh SWAMP_HOME. Read the run at boot and again 70 s later.
  2. Same checkout. Restart the original serve within 90 s of its last tracker heartbeat, and read the run every 30 s for 4.5 minutes.

Expected

A run whose owning instance has stopped, and released the v3 writer lease, is settled as interrupted, and the settlement replicates.

Actual

  1. Second checkout:
    Restoring this checkout's copy … from replication lineage "000000000001"
    Skipping workflow run "53bf95b3-…" (workflow: "slow") — belongs to remote instance "47d96377-b0a3-4468-918e-8c74b06b2828"
    The run reads running at boot and 70 s later, and stays that way for as long as that serve runs.
  2. Same checkout:
    Recovering work an interrupted command left in this checkout…
    Skipping workflow run "53bf95b3-…" (workflow: "slow") — tracker reports still running
    The run reads running for the whole 4.5 minutes. The tracker row had been reopened as running. reapDeadProcessRuns skips it because the row carries the old instance id, and reapStaleRuns needs a heartbeat older than 90 s; serve 2 booted about 54 s after the last one. The reap runs only at boot.

The run healed only when the original checkout restarted more than 90 s after the last heartbeat (Reaping orphaned workflow run … "tracker confirmed stale"). That restart also logged that it dropped 4 commit(s) the replica never confirmed: another checkout wrote to the datastore first, so they are lost.

Analysis

  • reapOrphanedWorkflowRuns (src/domain/workflows/orphaned_run_reaper.ts) skips a run with a foreign instance id when no heartbeat lookup is given ("belongs to remote instance"). On v3, serve passes none, because hasRemoteControlPlane is false.
  • The bucket already records that a v3 writer stopped: its lease release (for example released-000000000002). The reaper could use that, or the stopped serve could leave a record that its runs are orphaned.
  • The same-checkout skip comes from a tracker row that shutdown never settles. #3958 tracks that for format 2.
02Bog Flow
◉OPEN○TRIAGED○IN PROGRESS○SHIPPED

Open

10/26/2026, 2:43:00 PM

No activity in this phase yet.

03Sludge Pulse

Sign in to post a ripple.