github/spec-kit · error · BundlerError
Catalog source '{source_id}' has a non-integer priority: {pr
Error message
Catalog source '{source_id}' has a non-integer priority: {priority!r}. What it means
Raised by CatalogSource.from_dict()'s first priority guard when the 'priority' value is of a disallowed type: booleans are rejected explicitly (bool is a subclass of int in Python), and anything that is not an int or str is rejected outright (float, list, dict, None-like objects). Numeric strings are deferred to a later int() conversion (see error 69) rather than raised here.
Source
Thrown at src/specify_cli/bundler/models/catalog.py:82
@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,
)
def to_dict(self) -> dict[str, Any]:
return {View on GitHub (pinned to bf88c9f9a8)
Solutions
- Set priority to a plain integer (e.g. 10) or an integer-valued string (e.g. "10").
- Never use true/false for priority; YAML users should quote values that could parse as booleans.
- Fix the upstream generator to emit int(priority) when writing config.
Example fix
# before (YAML) priority: true # after (YAML) priority: 10
Defensive patterns
Strategy: type-guard
Validate before calling
p = entry.get("priority")
if isinstance(p, bool) or not isinstance(p, (int, str)):
raise ValueError(f"priority must be int or int-string, got {type(p).__name__}") Type guard
def is_valid_priority_type(p: object) -> bool:
return (isinstance(p, int) and not isinstance(p, bool)) or isinstance(p, str) Try / catch
try:
CatalogSource.from_dict(entry, Scope.PROJECT)
except BundlerError as e:
if "non-integer priority" in str(e):
entry["priority"] = int(float(entry["priority"])) # deliberate coercion policy Prevention
- Write priorities as plain integers in config.
- Beware YAML truthiness: never use true/false for priority.
- Config generators should coerce with int() at write time, not read time.
When it happens
Trigger: priority: true in YAML (parses as bool); priority: 1.5 (float); priority: [10] or {"value": 10}; priority set to a nested object by templating code.
Common situations: YAML where 'true'/'on' is used as a truthy priority; JSON producers serializing floats where ints were intended; config generated by code that inserts a raw Python object.
Related errors
- Catalog source '{source_id}' is missing its 'priority'.
- Malformed catalog config at {path}: expected a mapping at th
- Malformed catalog config at {path}: 'catalogs' must be a lis
- Malformed catalog config at {path}: each catalog entry must
- A catalog url is required.
AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14).
Data as JSON: /api/errors/564c446a186ac409.
Report an issue: GitHub.