github/spec-kit · error · PresetError

Invalid preset catalog format from {url}

Error message

Invalid preset catalog format from {url}

What it means

The catalog JSON object is missing one or both required top-level keys: `schema_version` and `presets`. Both are mandatory; the catalog format version drives forward compatibility, so an object without them is treated as an invalid catalog. The URL is included to identify which stacked catalog is at fault.

Source

Thrown at src/specify_cli/presets/__init__.py:4253

        Args:
            catalog_data: Parsed JSON payload from the catalog source.
            url: Source URL — used in the error message so the user can
                tell which catalog in a multi-catalog stack is malformed.

        Raises:
            PresetError: If the payload's shape is invalid.
        """
        if not isinstance(catalog_data, dict):
            raise PresetError(
                f"Invalid preset catalog format from {url}: "
                "expected a JSON object"
            )
        if (
            "schema_version" not in catalog_data
            or "presets" not in catalog_data
        ):
            raise PresetError(f"Invalid preset catalog format from {url}")
        if not isinstance(catalog_data.get("presets"), dict):
            raise PresetError(
                f"Invalid preset catalog format from {url}: "
                "'presets' must be a JSON object"
            )

    def _load_catalog_config(self, config_path: Path) -> Optional[List[PresetCatalogEntry]]:
        """Load catalog stack configuration from a YAML file.

        Args:
            config_path: Path to preset-catalogs.yml

        Returns:
            Ordered list of PresetCatalogEntry objects, or None if file
            doesn't exist or contains no valid catalog entries.

        Raises:
            PresetValidationError: If any catalog entry has an invalid URL,

View on GitHub (pinned to bf88c9f9a8)

Solutions

  1. Add both keys: `schema_version` (check existing public catalogs for the current value) and `presets` (an object keyed by preset id).
  2. Model your catalog on a known-good one served by the spec-kit project.
  3. Validate locally before publishing: both keys present, presets is an object.

Example fix

# before
{
  "presets": { "my-preset": { ... } }
}

# after
{
  "schema_version": 1,
  "presets": { "my-preset": { ... } }
}
Defensive patterns

Strategy: validation

Validate before calling

data = json.load(urllib.request.urlopen(url))
assert "schema_version" in data and "presets" in data, "catalog missing schema_version/presets"

Type guard

def has_catalog_required_keys(payload: dict) -> bool:
    return isinstance(payload, dict) and "schema_version" in payload and "presets" in payload

Try / catch

try:
    manager.refresh_catalogs()
except PresetError as e:
    if "Invalid preset catalog format" in str(e):
        # message names the URL; fix that catalog document's keys and retry
        ...

Prevention

When it happens

Trigger: A catalog document like {"presets": {...}} (no schema_version), {"schema_version": 1} (no presets), or an unrelated JSON object entirely (e.g. a package.json) served at the catalog URL.

Common situations: Hand-authoring a catalog and forgetting schema_version, or pointing the URL at the wrong JSON file in the repo.

Related errors


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