Skip to main content
← Back to list
01Issue
BugShippedSwamp CLIPublic
Assigneeshammz

Relationships

#2247 serve: poller pull can race a handler's delete-then-push and resurrect the deleted item

Opened by hammz · 9/17/2026· Shipped 9/17/2026

Summary

Serve's pollers (config, access-data and runtime-data, every 30s) call syncService.pullChanged() with no coordination with the WebSocket mutation handlers. A handler delete is a two-step unit of work:

  1. Remove the item from the local cache (per-path markDirty).
  2. Call pushChanged(), which deletes remote objects for dirty paths that are absent on disk.

If a poller pull reads the remote index before step 2 commits and downloads the item after step 1, the item is back on disk when the push runs. The push then sees the dirty path present and re-uploads it instead of deleting it. The delete is silently undone.

Scope

  • This affects every serve handler that deletes: model delete, workflow delete, and data delete/rename/gc/prune/run gc once swamp-club#2240 adds their missing push.
  • swamp-club#2240 shrinks the window from "until some unrelated push" to the push's own latency. This issue is about closing it.
  • swamp-club#2246 (s3-datastore ignoring subdirs) makes every poller walk the whole datastore, which makes the race more likely.

Reproduction notes

This was observed as part of the #2240 reproduction against local MinIO (managedConfig: true, hydrationStrategy full). Without the #2240 push, the config poller restored a deleted data item within about 4s. With the push in place, the race needs a poll to overlap the delete-to-push window, so a deterministic reproduction needs a slow push or an injected delay.

Possible directions

  • Serialize poller pulls with handler mutation+push through a serve-wide async lock.
  • Have pullChanged skip paths currently in the local dirty set.
  • Record deletions as tombstones in the dirty tracking instead of relying on absence on disk.

Expected

A delete over --server is never undone by a concurrent poll.

02Bog Flow
OPENTRIAGEDIN PROGRESSSHIPPED+ 1 MOREASSIGNED+ 8 MOREREVIEW+ 7 MOREPR_MERGED+ 2 MORESESSION_SUMMARIZED

Shipped

9/17/2026, 9:38:08 PM

Click a lifecycle step above to view its details.

03Sludge Pulse
hammz assigned hammz9/17/2026, 8:21:44 PM

Sign in to post a ripple.