github/spec-kit · error · ExtensionError
Invalid JSON in catalog: {e}
Error message
Invalid JSON in catalog: {e} What it means
Companion to the URLError case on the single-catalog path: the HTTP fetch succeeded but json parsing of the response body raised JSONDecodeError, so the catalog is declared invalid JSON with the parse error included.
Source
Thrown at src/specify_cli/extensions/__init__.py:4121
)
# Save cache metadata
metadata = {
"cached_at": datetime.now(timezone.utc).isoformat(),
"catalog_url": catalog_url,
}
self.cache_metadata_file.write_text(
json.dumps(metadata, indent=2), encoding="utf-8"
)
except OSError:
pass # Cache is best-effort; proceed with fetched data
return catalog_data
except urllib.error.URLError as e:
raise ExtensionError(f"Failed to fetch catalog from {catalog_url}: {e}")
except json.JSONDecodeError as e:
raise ExtensionError(f"Invalid JSON in catalog: {e}")
def search(
self,
query: Optional[str] = None,
tag: Optional[str] = None,
author: Optional[str] = None,
verified_only: bool = False,
) -> List[Dict[str, Any]]:
"""Search catalog for extensions across all active catalogs.
Args:
query: Search query (searches name, description, tags)
tag: Filter by specific tag
author: Filter by author name
verified_only: If True, show only verified extensions
Returns:
List of matching extension metadata, each annotated withView on GitHub (pinned to bf88c9f9a8)
Solutions
- Inspect the actual body: `curl -s <catalog_url> | head -c 400`
- Use the raw JSON endpoint rather than a UI/auth-wrapped page
- Fix credentials or headers the catalog server requires so it serves JSON
- Re-validate and re-upload edited catalog files after `python -m json.tool` passes
Defensive patterns
Strategy: validation
Validate before calling
import json, urllib.request
def probe_catalog_json(url: str) -> bool:
with urllib.request.urlopen(url, timeout=10) as r:
head = r.read(1)
if not head:
return False
r2 = urllib.request.urlopen(url, timeout=10)
try:
json.loads(r2.read())
return True
except json.JSONDecodeError:
return False Try / catch
from specify_cli.extensions import ExtensionError
try:
results = catalog.search(query='ci')
except ExtensionError as e:
if 'Invalid JSON in catalog' in str(e):
# body wasn't JSON: inspect with curl, fix auth/raw-URL, then retry Prevention
- Smoke-test catalog URLs (status 200 + parses as JSON) in a pre-deploy step
- Prefer raw file hosts for catalog JSON to avoid HTML envelopes
When it happens
Trigger: catalog_url returns non-JSON bytes: an HTML error/login page with 200 status, an empty body, truncated output from a flaky proxy, or JSON with a syntax error.
Common situations: Auth-protected catalog returning an HTML login page; object-storage URL serving an XML error document; hand-edited catalog uploaded with a trailing comma; CDN serving a partial response on timeout.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Invalid JSON in catalog from {entry.url}: {e}
- Could not query extension catalog: {catalog_error}
- Invalid catalog format from {url}: expected a JSON object
- Invalid catalog format from {url}
- Invalid catalog format from {url}: 'extensions' must be a JS
AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14).
Data as JSON: /api/errors/6da9b5b32ea86bd3.
Report an issue: GitHub.