Relationships
#658 extension pull: detect ghost-row conflicts and suggest swamp doctor extensions
Opened by josephholsten · 6/16/2026· Shipped 6/16/2026
Problem
When a local extension's source files are deleted directly (e.g. via `rm -rf`) without going through swamp commands, the catalog retains stale rows claiming the deleted type names. When `swamp extension pull` is subsequently run for a marketplace extension with the same type names, it hits the duplicate-type check and emits a hard error — even though the conflicting source files no longer exist on disk.
Reproduction
```bash
1. Create local in-tree stubs claiming the same types as a marketplace extension
mkdir -p /tmp/test-repo/extensions/models/foo cat > /tmp/test-repo/extensions/models/foo/bar.ts <<'TS' import { z } from "npm:zod@4"; export const model = { type: "@example/foo/bar", version: "0.0.0", globalArguments: z.object({}), resources: {}, methods: {} }; TS
2. Init swamp repo — triggers catalog indexing
cd /tmp/test-repo && swamp repo init
3. Trigger indexing
swamp model type search foo
4. Delete files directly (bypassing swamp)
rm -rf extensions/models/foo
5. Pull the marketplace extension with the same type names
swamp extension pull @example/foo
→ Error: Type "@example/foo/bar" (kind=model) is already claimed by
@example/foo@x.y.z at .swamp/pulled-extensions/.../bar.ts.
Cannot install @local/test-repo@0.0.0 at .../extensions/models/foo/bar.ts
— filesystem changes rolled back.
Run `swamp extension rm @example/foo` first if you intended to replace it.
```
The suggested fix (`swamp extension rm`) doesn't help — the extension isn't installed. The stale rows are from the deleted local source, not a pulled extension.
Workaround
Running `swamp doctor extensions` transitions the rows from `ValidationFailed` → `OrphanedBundleOnly`, which unblocks the subsequent pull. But this is non-obvious and requires knowing about `doctor`.
Proposed behavior
At conflict-check time, `swamp extension pull` should check whether the conflicting source path exists on disk. If the path is missing:
- Emit a targeted warning instead of the generic duplicate-type error:
`"Ghost catalog entry detected for
(source deleted outside swamp). Run `swamp doctor extensions` to reclassify and retry."` - Still block the pull (conflict must be resolved first), but point at the exact fix
The current generic error message suggests `swamp extension rm`, which is the wrong command for this case and leaves users stuck.
Why not auto-heal during pull?
Silently mutating the catalog during a pull conflates two operations. A targeted warning with a pointer to `doctor` is the right boundary — the catalog repair stays in one place with its own audit trail.
Environment
- swamp version: 20260609.210430.0
Shipped
Click a lifecycle step above to view its details.
stack72 commented 6/16/2026, 8:06:46 PM
Thanks @josephholsten 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.