#201 Catalog retains stale source-file entries when extension version drops a file; no native prune/repair
Opened by bixu · 5/1/2026
Summary
.swamp/_extension_catalog.db accumulates rows for source files that an extension removes in a later version. The stale rows continue to participate in model-type resolution and produce intermittent runtime failures ("No such file or directory: .../fetch_kubeconfig.js") and silently-wrong behavior (the older bundle path's logic runs instead of the newer one).
There is no native command to prune the catalog. Confirmed: swamp extension rm <name> followed by swamp extension pull <name> does NOT prune the stale row — after both commands complete cleanly, the catalog still contains both the old and new bundle_types entries, and resolution non-deterministically picks the old one.
swamp doctor extensions passes ("5 passed, 0 failed — OVERALL: PASS") even though the catalog points at non-existent files.
Reproduction
- Pull
@hivemq/harvester/[email protected]— this version ships two files:kubeconfig.tsandfetch_kubeconfig.ts. Both get rows inbundle_types. swamp extension update '@hivemq/harvester/kubeconfig'upgrades to2026.05.01.38— dropsfetch_kubeconfig.ts. Pulled-extensions and bundle dir are rewritten without that file.bundle_typesstill has both rows:
('.../kubeconfig.ts', '@hivemq/harvester/kubeconfig', 'model', '.../bundles/738c72f8/harvester/kubeconfig.js', '2026.05.01.38', ...)
('.../fetch_kubeconfig.ts', '@hivemq/harvester/kubeconfig', 'model', '.../bundles/738c72f8/harvester/fetch_kubeconfig.js', '2026.04.21.3', ...)The second source path no longer exists on disk; its bundle path no longer exists either.
4. Running swamp model method run non-deterministically picks one of the two rows. Symptoms: sometimes FTL error Method execution failed: No such file or directory ... fetch_kubeconfig.js; sometimes silently runs the v2026.04.21.3 code path (confirmed via log-message text — the older bundle's log line Renaming context '{from}' → '{to}' is emitted instead of the newer Renaming context/cluster/user to '{to}').
5. swamp extension rm '@hivemq/harvester/kubeconfig' --json followed by swamp extension pull '@hivemq/harvester/kubeconfig' --force does NOT prune the stale row. The native repair path is broken.
6. swamp doctor extensions reports OVERALL: PASS while this is happening.
Why this matters
It looks exactly like a bug in the extension's own logic. Users (and agents) chase the wrong root cause. In our session this consumed ~30 minutes of debugging and led an agent to do rm -rf .swamp/bundles && rm .swamp/_extension_catalog.db* cache surgery before finding the right answer. The "obvious" repair (extension rm + extension pull) does not work.
Asks (any subset)
swamp extension pull/updateshould prunebundle_typesrows whosesource_pathis not in the freshly-extracted set for the same extension.swamp extension rmshould remove allbundle_typesrows tagged with the extension being removed (currently it does not).swamp doctor extensionsshould detect orphan catalog rows (bundle_pathdoes not exist on disk, orsource_pathdoes not exist on disk) and surface them as failures with a one-line repair hint.- Add a native prune command, e.g.
swamp extension reindex <name>orswamp extension repair, that deletes catalog rows for missing files and rebuilds from the pulled-extensions tree. - Make resolution deterministic when multiple rows exist for the same
(type, kind)— pick the one whosebundle_pathexists, or error loudly.
Environment
- swamp
20260501.010449.0-sha.c24fb601 - Catalog db schema:
bundle_meta(key, value),bundle_types(source_path, type_normalized, kind, bundle_path, version, description, extends_type, source_mtime, source_fingerprint)
Closed
No activity in this phase yet.