github/spec-kit · error · BundlerError

Catalog source '{source_id}' is missing its 'priority'.

Error message

Catalog source '{source_id}' is missing its 'priority'.

What it means

Raised by CatalogSource.from_dict() when a source mapping omits 'priority' entirely (data.get('priority') is None). Priority is required because the effective source stack is priority-sorted across project, user, and built-in scopes; there is no implicit default when reading raw config.

Source

Thrown at src/specify_cli/bundler/models/catalog.py:80

    scope: Scope = Scope.PROJECT

    @property
    def install_allowed(self) -> bool:
        return self.install_policy is InstallPolicy.INSTALL_ALLOWED

    @classmethod
    def from_dict(cls, data: Any, scope: Scope) -> "CatalogSource":
        if not isinstance(data, dict):
            raise BundlerError("Each catalog source must be a mapping.")
        source_id = str(data.get("id", "")).strip()
        url = str(data.get("url", "")).strip()
        if not source_id:
            raise BundlerError("A catalog source is missing its 'id'.")
        if not url:
            raise BundlerError(f"Catalog source '{source_id}' is missing its 'url'.")
        priority = data.get("priority")
        if priority is None:
            raise BundlerError(f"Catalog source '{source_id}' is missing its 'priority'.")
        if isinstance(priority, bool) or not isinstance(priority, (int, str)):
            raise BundlerError(
                f"Catalog source '{source_id}' has a non-integer priority: {priority!r}."
            )
        try:
            priority_int = int(priority)
        except (TypeError, ValueError):
            raise BundlerError(
                f"Catalog source '{source_id}' has a non-integer priority: {priority!r}."
            ) from None
        return cls(
            id=source_id,
            url=url,
            priority=priority_int,
            install_policy=InstallPolicy.parse(data.get("install_policy")),
            scope=scope,
        )

View on GitHub (pinned to bf88c9f9a8)

Solutions

  1. Add an integer 'priority' to the source mapping (lower typically wins in the sorted stack — check your stack's sort direction convention).
  2. If creating sources programmatically, use add_source(root, id, url, priority=N, policy=...) which requires priority explicitly and stores int(priority).
  3. Ensure YAML entries are not 'priority:' with no value.

Example fix

# before
{"id": "example", "url": "https://example.com/c.json", "install_policy": "install-allowed"}

# after
{"id": "example", "url": "https://example.com/c.json", "priority": 10, "install_policy": "install-allowed"}
Defensive patterns

Strategy: validation

Validate before calling

if entry.get("priority") is None:
    raise ValueError("source entry missing 'priority'")
CatalogSource.from_dict(entry, Scope.PROJECT)

Type guard

def has_priority(entry: dict) -> bool:
    return isinstance(entry, dict) and entry.get("priority") is not None

Try / catch

try:
    CatalogSource.from_dict(entry, Scope.PROJECT)
except BundlerError as e:
    if "missing its 'priority'" in str(e):
        entry["priority"] = 100  # apply your default, then retry

Prevention

When it happens

Trigger: A config entry with id/url/policy but no priority key; priority explicitly set to null in JSON; hand-authored entries copied from a schema that made priority optional.

Common situations: Hand-writing config from memory; older configs written before priority existed; YAML with 'priority:' left empty (parses as None).

Related errors


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