Skip to main content
← Back to list
01Issue
BugShippedSwamp CLI
Assigneesstack72

Relationships

#851 autoGc emits auto_gc_completed event on --json stdout, breaking single-parse consumers

Opened by mgreten · 6/27/2026· Shipped 6/28/2026

First — thank you for shipping auto-GC (#823), it's exactly the inline-cleanup mechanism I'd hoped for. I hit one side effect worth flagging.

What happens

With autoGc: true enabled, swamp model method run <model> <method> --json emits a second JSON object on stdout after the result: the method's result object (pretty-printed), immediately followed by a line like:

{"event":"auto_gc_completed","versionsDeleted":2,"bytesReclaimed":7508}

So the --json stdout is now two concatenated JSON values. Any consumer that does a single parse of the output breaks:

  • python3 -c "import sys,json; json.load(sys.stdin)"json.decoder.JSONDecodeError: Extra data: line N column 1
  • Ruby JSON.parse(stdout) → raises on the trailing object.

In my case this broke several poller bridge scripts and an internal Ruby shellout helper that all consume --json with a single parse — they'd worked fine until autoGc was enabled, then started failing on every run that triggered a collection. Disabling autoGc immediately restored clean single-object --json output and everything parsed again.

Why it's worth fixing

The whole point of --json is machine-readable, single-document output for piping into a parser. An auto-GC lifecycle event appended to that stream means --json is no longer reliably parseable by the most common consumer pattern (one parse of stdout). It also means enabling autoGc silently changes the output contract of every method run for every downstream tool.

A few directions that could work

  • Keep the auto_gc_completed event off stdout under --json — emit it to stderr, or to the log stream, or fold it into the single result object (e.g. a gc: field on the existing result) rather than as a second top-level document.
  • Or gate the event line behind a verbose/non-json mode so --json stays single-document.

Whichever fits — the key property is that --json stdout stays exactly one JSON value regardless of whether auto-GC fired.

Repro

  1. Set autoGc: true in .swamp.yaml on an @swamp/s3-datastore repo with some collectable (expired/excess-version) data.
  2. swamp model method run <model> <method> --json | python3 -c "import sys,json;json.load(sys.stdin)"
  3. On a run where auto-GC collects something → JSONDecodeError: Extra data. Disabling autoGc → clean parse.

Environment

  • @swamp/s3-datastore@2026.06.26.1
  • swamp 20260626.202321.0

Thanks again — happy to share fuller sample output if useful.

02Bog Flow
OPENTRIAGEDIN PROGRESSSHIPPED+ 1 MOREASSIGNED+ 4 MOREREVIEW+ 3 MOREPR_MERGED+ 1 MORECONTRIBUTOR_NOTIFIED

Shipped

6/28/2026, 4:31:17 AM

Click a lifecycle step above to view its details.

03Sludge Pulse
stack72 assigned stack726/28/2026, 3:55:32 AM
Editable. Press Enter to edit.

mgreten commented 6/27/2026, 2:17:45 AM

Wow... Claude got a little snarky in that stuff above. Super thankful for everything you all do!

stack72 commented 6/28/2026, 4:31:27 AM

Thanks @mgreten for reporting this! The fix has been merged and a release is on its way. We appreciate your contribution to swamp.

mgreten commented 6/29/2026, 1:59:35 PM

Confirmed fixed on swamp 20260629.120229.0 — thank you for the quick turnaround!

I verified it both in an isolated repo and against our live shared MinIO datastore: with autoGc: true and collectable data present, a swamp model method run … --json now emits exactly one JSON object on stdout, the auto_gc_completed event no longer appears on the stream, and collection still fires (versions got trimmed to the cap on disk). Our single-parse poller bridges and the Ruby shellout helper parse cleanly again.

We've re-enabled autoGc: true on our high-churn namespaces — it's a great fit for keeping the index from accreting. Really appreciate the work on this one.

Sign in to post a ripple.