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

Relationships

#1440 data delete removes data locally but push reports 'no changes' — next datastore sync restores everything

Opened by magistr · 7/28/2026

Summary

swamp data delete removes the data locally and reports a successful deletion, but the follow-up push reports Push complete, no changes — the deletion is never propagated to the datastore. The next command that syncs the model (any model method run) pulls every "deleted" artifact back.

The result is that deleted data silently reappears, and swamp data delete is effectively a no-op on a sync-backed repo.

Reproduction

Repo backed by a remote datastore (mine is @keeb/mongodb-datastore; I have not been able to test a filesystem datastore, see Scope below). Any model with data will do.

$ swamp data query 'modelName == "vecs"' --select 'name' --json
{"results": ["framework-strategy","framework","skill-finishing","courses"], "total": 4}

$ swamp data delete vecs --all --yes --json
 system │ Syncing model @magistr/vecs/school/a3d64e0a-… from datastore...
{
  "modelId": "a3d64e0a-1823-42c0-a75e-bd66f5b20d7d",
  "modelName": "vecs",
  "totalDeleted": 6,
  "totalVersionsDeleted": 14,
  "failed": [],
  "dryRun": false
}
 system │ Pushing changes to datastore...
 system │ Push complete, no changes          <-- 6 artifacts / 14 versions just went away

$ swamp data query 'modelName == "vecs"' --select 'name' --json
{"results": [], "total": 0}                  <-- looks deleted

$ swamp model method run vecs courses --quiet
 system │ Syncing model @magistr/vecs/school/a3d64e0a-… from datastore...
   Completed   courses on vecs succeeded in 47ms

$ swamp data query 'modelName == "vecs"' --select 'name' --json
{"results": ["framework-strategy","framework","skill-finishing","courses"], "total": 4}

All four artifacts are back. The courses method writes only the courses resource — it does not and cannot produce framework, framework-strategy or skill-finishing. Those three can only have come from the datastore sync, so this is restoration, not re-creation.

The deletion is local-only

The local files really are removed, so the bug is in propagating the deletion, not in performing it:

$ ls -1 ~/.swamp/repos/<repo>/data/@magistr/vecs/school/<modelId>
courses
framework
framework-strategy
report-swamp-method-summary
report-swamp-method-summary-json
skill-finishing

$ swamp data delete vecs --all --yes --json   # → "Push complete, no changes"

$ ls -1 ~/.swamp/repos/<repo>/data/@magistr/vecs/school/<modelId>
(empty)

So data delete unlinks the local tree, the push diff computes zero changes from that, and the next pull faithfully restores the remote copy.

Expected

Either:

  1. the push detects removed local paths and propagates the deletion (tombstone / remote delete), so the artifacts stay deleted; or
  2. data delete fails loudly on a sync-backed repo rather than reporting totalDeleted: 6 for a deletion that will not survive the next sync.

Silently reporting success for a deletion that gets rolled back is the worst of the three outcomes.

Actual

data delete reports success, the query confirms it, and the data comes back on the next sync with no warning.

Impact

  • Deleted data reappears with no indication anything went wrong.
  • The obvious "it needed a second pass" reading is a red herring: a second data delete also appears to work, because the verifying query runs without an intervening sync. It only looks fixed until the next method run.
  • There is no working way to remove a model's data short of swamp model delete <name> --force and recreating the model, which changes the model's UUID and orphans the old data.
  • swamp data gc is not a usable workaround here: it is repo-wide rather than model-scoped, and in my repo it ran for over 5 minutes without completing, held the global lock long enough to be reported stale (Global lock held by … appears stale (exceeded TTL of 30000ms) — proceeding), and pushed 66022 files when interrupted.

Scope / ownership

I am filing this against swamp itself because Push complete, no changes comes from the core sync orchestration, and it computed "no changes" after six directories were removed from the local data tree — that reads like the push diff not modelling deletions at all.

If deletion propagation is instead delegated to the datastore provider's createSyncService, then this belongs to @keeb/mongodb-datastore and should be re-routed. I could not isolate that from outside the binary. Happy to re-test against a filesystem datastore if that would help narrow it.

Possibly related: #1280 (sync guard skipping a directory during push → 0 files pushed) looks like the same family of "push computed nothing to do when it should have", though that one is namespace-specific.

Environment

  • swamp 20260727.193526.0-sha.03dabbb5
  • datastore: @keeb/mongodb-datastore — MongoDB RS rs0, database swamp, namespace t_default_r_dev-tmp-swamp, healthy, 75ms latency
  • macOS (Darwin 23.6.0), arm64
  • Reproduced repeatedly, including on a freshly created model instance.
02Bog Flow
OPENTRIAGEDIN PROGRESSSHIPPED

Open

7/28/2026, 10:12:52 AM

No activity in this phase yet.

03Sludge Pulse

Sign in to post a ripple.