github/spec-kit · error · ExtensionError
Invalid catalog format from {url}
Error message
Invalid catalog format from {url} What it means
Second stage of catalog validation: the payload is a JSON object but is missing either the schema_version or the extensions key (or both). Both keys are mandatory for a spec-kit extension catalog, so an object lacking them is rejected as an invalid catalog format.
Source
Thrown at src/specify_cli/extensions/__init__.py:3694
object and the nested mapping (see ``integrations/catalog.py``);
the extension catalog must stay consistent so a malformed payload
surfaces as the user-facing ``Invalid catalog format`` error
instead of a raw Python traceback.
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:
ExtensionError: If the payload's shape is invalid.
"""
if not isinstance(catalog_data, dict):
raise ExtensionError(
f"Invalid catalog format from {url}: expected a JSON object"
)
if "schema_version" not in catalog_data or "extensions" not in catalog_data:
raise ExtensionError(f"Invalid catalog format from {url}")
if not isinstance(catalog_data.get("extensions"), dict):
raise ExtensionError(
f"Invalid catalog format from {url}: 'extensions' must be a JSON object"
)
def get_active_catalogs(self) -> List[CatalogEntry]:
"""Get the ordered list of active catalogs.
Resolution order:
1. SPECKIT_CATALOG_URL env var — single catalog replacing all defaults
2. Project-level .specify/extension-catalogs.yml
3. User-level ~/.specify/extension-catalogs.yml
4. Built-in default stack (default + community)
Returns:
List of CatalogEntry objects sorted by priority (ascending)
Raises:View on GitHub (pinned to bf88c9f9a8)
Solutions
- Add both required keys to the catalog document: schema_version (e.g. 1) and extensions (object keyed by extension id)
- Check for key typos — plural 'extensions' and exact 'schema_version' are required
- Validate locally before publishing: `python -c "import json;d=json.load(open('catalog.json'));assert {'schema_version','extensions'} <= d.keys()"`
- If you don't control the URL, remove it from the catalog config and rely on the built-in default+community stack
Example fix
# before
{
"extensions": { "my-ext": {"name": "My Ext"} }
}
# after
{
"schema_version": 1,
"extensions": { "my-ext": {"name": "My Ext"} }
} Defensive patterns
Strategy: validation
Validate before calling
REQUIRED_CATALOG_KEYS = {'schema_version', 'extensions'}
def catalog_has_required_keys(data: dict) -> bool:
return REQUIRED_CATALOG_KEYS <= data.keys() Type guard
def is_catalog_shaped(data: object) -> bool:
return (
isinstance(data, dict)
and 'schema_version' in data
and 'extensions' in data
and isinstance(data['extensions'], dict)
) Prevention
- Copy the documented catalog skeleton rather than authoring from scratch
- Run a schema assertion in the catalog's publish pipeline
When it happens
Trigger: A catalog URL returning `{"data": ...}` or an extensions-only object without schema_version; any object payload where 'schema_version' not in catalog_data or 'extensions' not in catalog_data evaluates true.
Common situations: Hand-authoring a catalog and omitting schema_version; server returning a generic API envelope ({'status':'ok',...}); typos like extension/version singular forms.
Related errors
- Invalid catalog format from {url}: expected a JSON object
- Invalid catalog format from {url}: 'extensions' must be a JS
- Invalid JSON in catalog from {entry.url}: {e}
- Invalid JSON in catalog: {e}
- Invalid preset catalog format from {url}
AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14).
Data as JSON: /api/errors/e93dba195c730378.
Report an issue: GitHub.