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 = None

View on GitHub (pinned to bf88c9f9a8)

Solutions

  1. Fix the catalog payload to use unquoted JSON booleans: "verified": true or false.
  2. Fix the catalog generator to use a real JSON serializer (json.dumps) rather than string templating.
  3. 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

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


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