Relationships
#1440 data delete removes data locally but push reports 'no changes' — next datastore sync restores everything
Opened by magistr · 7/28/2026· Shipped 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:
- the push detects removed local paths and propagates the deletion (tombstone / remote delete), so the artifacts stay deleted; or
data deletefails loudly on a sync-backed repo rather than reportingtotalDeleted: 6for 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 deletealso appears to work, because the verifying query runs without an intervening sync. It only looks fixed until the nextmethod run. - There is no working way to remove a model's data short of
swamp model delete <name> --forceand recreating the model, which changes the model's UUID and orphans the old data. swamp data gcis 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 RSrs0, databaseswamp, namespacet_default_r_dev-tmp-swamp, healthy, 75ms latency - macOS (Darwin 23.6.0), arm64
- Reproduced repeatedly, including on a freshly created model instance.
Shipped
Click a lifecycle step above to view its details.