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-datastore2026.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:
- Second checkout. Start serve in a copy of the repo without
.swamp/and with a freshSWAMP_HOME. Read the run at boot and again 70 s later. - 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
- Second checkout:
The run readsRestoring this checkout's copy … from replication lineage "000000000001" Skipping workflow run "53bf95b3-…" (workflow: "slow") — belongs to remote instance "47d96377-b0a3-4468-918e-8c74b06b2828"runningat boot and 70 s later, and stays that way for as long as that serve runs. - Same checkout:
The run readsRecovering work an interrupted command left in this checkout… Skipping workflow run "53bf95b3-…" (workflow: "slow") — tracker reports still runningrunningfor the whole 4.5 minutes. The tracker row had been reopened asrunning.reapDeadProcessRunsskips it because the row carries the old instance id, andreapStaleRunsneeds 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, becausehasRemoteControlPlaneis 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.
Open
No activity in this phase yet.
Sign in to post a ripple.