github/spec-kit · error · BundlerError
No project-scoped catalog source matching '{target}' was fou
Error message
No project-scoped catalog source matching '{target}' was found. What it means
Raised by remove_source() when neither the exact id/url match nor the canonicalized-url fallback finds a matching project-scoped source. remove_source only inspects the project catalog config (not user or built-in scopes), and the canonicalization fallback is deliberately conservative so it never deletes a different source whose url happens to equal a bare id's canonicalized path.
Source
Thrown at src/specify_cli/bundler/commands_impl/catalog_config.py:228
f"'{target}' is a built-in default source and cannot be deleted "
"(add a same-id source to override it instead)."
)
catalogs = _read(project_root)
# Prefer an exact id/url match.
remaining = [c for c in catalogs if c.get("id") != target and c.get("url") != target]
if len(remaining) == len(catalogs):
# No exact match. add_source canonicalizes a local path to an absolute
# url before storing, so fall back to a canonicalized-url match -- this
# lets `remove ./cat.json` undo `add ./cat.json` (stored absolute).
# Only as a *fallback*: _canonicalize_url treats a bare id as a local
# path (empty scheme), so applying it unconditionally could also delete a
# different source whose url equals the id's canonicalized path.
canonical = _canonicalize_url(target)
if canonical != target:
remaining = [c for c in catalogs if c.get("url") != canonical]
if len(remaining) == len(catalogs):
raise BundlerError(
f"No project-scoped catalog source matching '{target}' was found."
)
_write(project_root, remaining)
return target
View on GitHub (pinned to bf88c9f9a8)
Solutions
- List the actual project sources first (catalog list / _read) and copy the exact id or stored url string to pass to remove_source.
- If you added with a relative path, pass the stored absolute url (or the id) rather than the relative path.
- For idempotent scripts, catch this BundlerError and treat 'not found' as success.
- Confirm the source is not user-scoped or built-in — those are not removable through this project-scoped API.
Example fix
# before
remove_source(root, "./cat.json") # stored as absolute url; may not match
# after
sources = read_sources(root)
match = next((s for s in sources if "cat.json" in s.url), None)
if match:
remove_source(root, match.id) Defensive patterns
Strategy: try-catch
Validate before calling
sources = catalog_config._read(root)
targets = {c.get("id") for c in sources} | {c.get("url") for c in sources}
if target not in targets:
# show user the available ids/urls instead of calling remove_source Try / catch
try:
remove_source(root, target)
except BundlerError as e:
if "was found" in str(e) and "No project-scoped" in str(e):
pass # idempotent cleanup: already absent
else:
raise Prevention
- Pass the exact stored id or absolute url (list sources first) rather than relative paths.
- Treat 'not found' as success in uninstall scripts.
- Remember this API is project-scope only — user/built-in sources are invisible to it.
When it happens
Trigger: Calling remove_source with a typo'd id or url; removing a source that was never added or already removed; removing a user-scoped or built-in source via the project-scoped API; passing a relative path that canonicalizes differently from how it was stored; passing a bare id whose canonicalized local path is empty-scheme and therefore not retried.
Common situations: Idempotent cleanup scripts that assume removal always succeeds; stale docs referencing an old source id; double-running an uninstall playbook; confusion between project scope and user scope sources.
Related errors
- '{target}' is a built-in default source and cannot be delete
- Bundle '{bundle_id}' is not installed.
- Preset '{component.id}' not found in any catalog.
- Extension '{component.id}' not found in any catalog.
- Malformed catalog config at {path}: expected a mapping at th
AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14).
Data as JSON: /api/errors/a1812aa630c97805.
Report an issue: GitHub.