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

  1. 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.
  2. To suppress a built-in's install capability, re-add it with install_policy='discovery-only'.
  3. If you genuinely need it gone from listings, filter it out in your own display layer; the stack always includes built-ins.
  4. 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

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


AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14). Data as JSON: /api/errors/6c06b8f2416dc9dc. Report an issue: GitHub.