data gc skips version-count GC when no lifetime-expired data exists
Opened by keeb · 4/13/2026· Shipped 4/14/2026
Bug
swamp data gc (interactive mode) returns early with No expired data found. Nothing to clean up. and never runs version-count garbage collection. Resources configured with lifetime: infinite, gc: <N> accumulate unbounded versions even when swamp data gc is run.
Repro
- Have a model resource configured with
lifetime: infiniteand a finite version GC count (e.g.gc: 10). - Write >N versions of that resource (I have 20,825 versions of one).
- Run
swamp data gc. - Observe:
No expired data found. Nothing to clean up.— nothing is pruned, disk usage unchanged.
Confirmed: swamp data versions <model> <name> --json reports "total": 20825 and swamp data get <model> <name> --no-content shows Lifetime: infinite | GC: 10.
Root cause
In src/cli/commands/data_gc.ts around lines 72–78:
if (cliCtx.outputMode === "log" && !options.force && !options.dryRun) {
const preview = await dataGcPreview(ctx, deps);
if (preview.items.length === 0) {
console.log("No expired data found. Nothing to clean up.");
return; // early return — never calls dataGc()
}
...
}dataGcPreview calls findExpiredData (src/domain/data/data_lifecycle_service.ts:182), which only finds lifetime-expired entries. It does not consider version-count overflow.
Phase 2 version GC (collectGarbage loop at data_lifecycle_service.ts:310-333) lives inside deleteExpiredData, which is only invoked by dataGc. When the preview returns empty, the early return skips that entirely.
Side effect: --force, --dry-run, and --json all bypass the preview branch, so version GC only works via those flags — which is surprising since the interactive default is the documented usage.
Suggested fix
The preview should also report models that have more versions than their GC policy allows (an "over-retention" category), and/or the early-return should be removed so Phase 2 always runs. Either way, the interactive default should not silently skip version-count GC.
Environment
- swamp
20260206.200442.0-sha.(binary on target) - Repo:
/opt/proxmox-manager(21 pulled extensions + 16 local workflows) - OS: Alpine Linux (running swamp inside a Debian-based docker container)
Shipped
Click a lifecycle step above to view its details.
Sign in to post a ripple.