github/spec-kit · error · BundlerError
'{target}' is a built-in default source and cannot be delete
Error message
'{target}' is a built-in default source and cannot be deleted (add a same-id source to override it instead). What it means
Raised by remove_source() when the id or url passed to remove matches one of the built-in default catalog source ids (_BUILTIN_IDS). Built-in sources form the always-present fallback of the source stack and cannot be deleted; the supported way to neutralize or replace one is to add a project-scoped source with the same id, which overrides the built-in at higher precedence.
Source
Thrown at src/specify_cli/bundler/commands_impl/catalog_config.py:209
raise BundlerError(
f"Catalog source '{resolved_id}' (or url) already exists in this project."
)
entry = {
"id": resolved_id,
"url": url,
"priority": int(priority),
"install_policy": install_policy.value,
}
catalogs.append(entry)
_write(project_root, catalogs)
return CatalogSource.from_dict(entry, Scope.PROJECT)
def remove_source(project_root: Path, id_or_url: str) -> str:
target = id_or_url.strip()
if target in _BUILTIN_IDS:
raise BundlerError(
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):View on GitHub (pinned to bf88c9f9a8)
Solutions
- To override a built-in, call add_source() with the same source_id and your desired url/priority/policy — same-id higher-precedence sources win.
- To suppress a built-in's install capability, re-add it with install_policy='discovery-only'.
- If you genuinely need it gone from listings, filter it out in your own display layer; the stack always includes built-ins.
- In 'remove all' scripts, skip ids found in _BUILTIN_IDS before calling remove_source.
Example fix
# before
remove_source(root, "official") # 'official' is a built-in -> raises
# after
add_source(root, "official", "https://mirror.example.com/catalog.json",
priority=10, policy="discovery-only") # overrides the built-in Defensive patterns
Strategy: validation
Validate before calling
BUILTIN_IDS = set(catalog_config._BUILTIN_IDS)
def remove_source_safe(root, target):
if target.strip() in BUILTIN_IDS:
return None # not removable; override via add_source with same id
return catalog_config.remove_source(root, target) Try / catch
try:
remove_source(root, target)
except BundlerError as e:
if "built-in default source" in str(e):
add_source(root, target, override_url, priority=1, policy="discovery-only")
else:
raise Prevention
- Never assume the catalog list is fully user-owned; filter built-ins before bulk remove.
- To neutralize a built-in, add a same-id project source with the desired policy instead of deleting.
- Read the built-in ids from _BUILTIN_IDS rather than hard-coding them.
When it happens
Trigger: Calling remove_source(project_root, '<builtin-id>') where <builtin-id> is listed in _BUILTIN_IDS; attempting to clean-slate the catalog by removing every source including defaults; scripting 'remove all' without filtering built-ins.
Common situations: Users trying to disable a default catalog they do not want; cleanup scripts that iterate the full stack and remove each source; misunderstanding that built-ins are code-defined, not entries in the project config file.
Related errors
- Catalog source '{resolved_id}' (or url) already exists in th
- No project-scoped catalog source matching '{target}' was fou
- Each catalog source must be a mapping.
- Malformed catalog config at {path}: expected a mapping at th
- Unsupported catalog config schema version '{str(schema_versi
AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14).
Data as JSON: /api/errors/6c06b8f2416dc9dc.
Report an issue: GitHub.