github/spec-kit · error · BundlerError
Catalog entry '{entry_id}': 'verified' must be a boolean (tr
Error message
Catalog entry '{entry_id}': 'verified' must be a boolean (true/false). What it means
Raised by _parse_verified() when a catalog entry's 'verified' flag is not an actual JSON boolean. Because bool('false') is truthy in Python, stringly-typed values would silently mark untrusted entries as verified, so only true booleans are accepted; anything else (including the strings 'true'/'false') is rejected.
Source
Thrown at src/specify_cli/bundler/models/catalog.py:131
"""
if value is None:
return ()
if isinstance(value, (str, bytes)) or not isinstance(value, (list, tuple)):
raise BundlerError(
f"Catalog entry '{entry_id}': 'tags' must be a list of strings."
)
return tuple(str(t) for t in value)
def _parse_verified(value: Any, entry_id: str) -> bool:
"""Validate a catalog entry's ``verified`` flag is a real boolean.
``bool("false")`` is truthy, so coercing arbitrary strings would silently
mark untrusted entries as verified; require an actual boolean instead.
"""
if isinstance(value, bool):
return value
raise BundlerError(
f"Catalog entry '{entry_id}': 'verified' must be a boolean (true/false)."
)
@dataclass(frozen=True)
class CatalogEntry:
id: str
name: str
version: str
role: str
description: str
author: str
license: str
download_url: str
requires_speckit_version: str
sha256: str | None = None
provides: dict[str, int] = field(default_factory=dict)
repository: str | None = NoneView on GitHub (pinned to bf88c9f9a8)
Solutions
- Fix the catalog payload to use unquoted JSON booleans: "verified": true or false.
- Fix the catalog generator to use a real JSON serializer (json.dumps) rather than string templating.
- If the flag is unknown, omit it — absent defaults to False, which is the safe direction.
Example fix
# before (catalog JSON) "verified": "true" # after (catalog JSON) "verified": true
Defensive patterns
Strategy: type-guard
Validate before calling
verified = entry.get("verified")
if verified is not None and not isinstance(verified, bool):
raise ValueError(f"verified must be a boolean, got {type(verified).__name__}") Type guard
def is_valid_verified(value: object) -> bool:
return value is None or isinstance(value, bool) Try / catch
try:
CatalogEntry.from_dict(entry_raw)
except BundlerError as e:
if "'verified' must be a boolean" in str(e):
entry_raw.pop("verified", None) # absent defaults to False (safe) Prevention
- Never template booleans as strings; use json.dumps for catalog generation.
- Omit 'verified' when unsure — the default False is the safe direction.
- Remember bool('false') is truthy in Python: never coerce strings to bool.
When it happens
Trigger: A remote catalog entry with "verified": "true" (quoted string); verified: 1 or "yes" in YAML; a catalog producer serializing booleans through a template engine that quotes everything.
Common situations: Template-generated catalogs (Jinja, mustache) that render booleans as strings; YAML configs using yes/no which some loaders coerce unpredictably; third-party catalogs authored in JSON-by-hand.
Related errors
- Catalog entry '{entry_id}': 'tags' must be a list of strings
- Each catalog entry must be a mapping.
- Catalog entry '{entry_id or '<unknown>'}': 'requires' must b
- Catalog entry '{entry_id or '<unknown>'}': 'provides' must b
- Catalog payload must be a JSON object.
AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14).
Data as JSON: /api/errors/548611a48e348d61.
Report an issue: GitHub.