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

Relationships

#1736 extension rm also deletes the lockfile entry, and install on an empty lockfile is a silent success — rm/install is not a round trip

Opened by esteban · 8/19/2026· Shipped 8/20/2026

Summary

swamp extension rm <name> removes the extension's files and its entry from extensions/models/upstream_extensions.json. Remove every extension and the lockfile is {}. swamp extension install then exits 0 reporting a clean success while restoring nothing — leaving a repo whose model types no longer load, and no indication that anything is wrong.

Why anyone does this

install --help reads:

Restore pulled extensions from the lockfile. Reads upstream_extensions.json and re-pulls any extensions whose source files are missing. Use after cloning a repo or in CI.

That is a promise about disaster recovery, so the obvious way to test it — before trusting it in CI or on a fresh clone — is rm everything, then install. That test cannot pass, and it fails silently.

rm --help says only "Remove a pulled extension and its files". Nothing there mentions the lockfile entry.

Reproduction

$ echo '{}' > extensions/models/upstream_extensions.json
$ swamp extension install --json
{"entries":[],"installed":0,"migrated":0,"upToDate":0,"failed":0}
$ echo $?
0

failed: 0, exit 0, no warning. Verified today on swamp 20260809.004828.0-sha.b61c9de2.

Reached the same state the honest way: rm all 8 pulled extensions one at a time, and the lockfile is {} at the end.

Impact

We ran this as a clean-room restore drill on a repo pinning 8 upstream extensions. The restore itself is excellent once the lockfile is intact — one swamp extension install gave installed=8, migrated=0, upToDate=0, failed=0, doctor extensions pass with 0 orphan files, workflow validate 34/34, model list byte-identical, 29 tests green. The only reason we could get there was that the lockfile is git-tracked, so git checkout -- extensions/models/upstream_extensions.json put it back.

A repo that gitignores it, or a rm sweep performed on an already-dirty tree, has no path back except re-pulling every extension by hand from memory — with no record of which versions were pinned, which is the whole point of the lockfile.

The working recipe, for the record:

swamp extension rm <each>
git checkout -- extensions/models/upstream_extensions.json   # the step nobody knows they need
swamp extension install --json

Suggested fix — either one is sufficient

  1. install should warn when the lockfile has no entries. Something like lockfile has no entries; nothing to restore instead of a clean success. Cheapest fix, and it also covers the clone/CI case the help text advertises, where an empty or unstaged lockfile is equally a misconfiguration worth failing loudly on. A non-zero exit would be defensible in CI, but a warning alone would have been enough for us.
  2. Give rm a way to keep the lockfile entry--keep-lock or similar — since "remove the artifacts but stay pinned" is precisely what testing a restore wants.

And regardless of which: rm --help should state that the lockfile entry is removed too.

Not a bug in rm by itself

Dropping the entry is defensible — rm means "I no longer want this extension", and leaving it pinned would make the next install resurrect it. The gap is that nothing tells you rm and install are not inverses, and that install does not notice it has nothing to do.

Environment

  • swamp 20260809.004828.0-sha.b61c9de2, Deno 2.8.3, Linux x86_64
  • 8 pinned upstreams across 4 collectives, filesystem datastore, lockfile git-tracked
02Bog Flow
OPENTRIAGEDIN PROGRESSSHIPPED+ 1 MOREASSIGNED+ 2 MOREREVIEW+ 4 MOREPR_MERGED+ 2 MORESESSION_SUMMARIZED

Shipped

8/20/2026, 7:23:00 AM

Click a lifecycle step above to view its details.

03Sludge Pulse
stack72 assigned stack728/20/2026, 6:38:36 AM
Editable. Press Enter to edit.

stack72 commented 8/20/2026, 7:23:09 AM

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

Sign in to post a ripple.