usestrix/strix · error · SpecParseError
{p} is not valid JSON or YAML: {exc}
Error message
{p} is not valid JSON or YAML: {exc} What it means
SpecParseError raised by load_spec when the file's text parses as neither JSON nor YAML (JSON is tried first for a clearer error; then yaml.safe_load). The chained YAMLError pinpoints the offending line/column. Note YAML is permissive, so this usually means genuinely malformed content, not a minor syntax slip.
Source
Thrown at strix/utils/api_spec.py:59
"""Load an API spec file as a mapping.
Raises :class:`SpecParseError` if the file cannot be read or is not a
JSON/YAML mapping.
"""
p = Path(path)
try:
text = p.read_text(encoding="utf-8")
except OSError as exc:
raise SpecParseError(f"Cannot read spec {p}: {exc}") from exc
# JSON is a subset of YAML, so safe_load parses both; try JSON first for a
# clearer error and to keep the fast path fast.
try:
data: Any = json.loads(text)
except json.JSONDecodeError:
try:
data = yaml.safe_load(text)
except yaml.YAMLError as exc:
raise SpecParseError(f"{p} is not valid JSON or YAML: {exc}") from exc
if not isinstance(data, dict):
raise SpecParseError(f"{p} does not contain a mapping at the top level")
return data
def classify_spec(raw: dict[str, Any]) -> str | None:
"""Return ``openapi`` / ``swagger`` / ``postman``, or ``None`` if unrecognized."""
if isinstance(raw.get("openapi"), str):
return "openapi"
if str(raw.get("swagger", "")).startswith("2"):
return "swagger"
info = raw.get("info")
if isinstance(info, dict) and ("_postman_id" in info or "item" in raw):
return "postman"
return None
def detect_spec_format(path: Path) -> str | None:View on GitHub (pinned to 8551339130)
Solutions
- Validate the file locally: python -c "import yaml,sys; yaml.safe_load(open(sys.argv[1]))" file
- Re-download the spec and confirm the content starts with '{' or 'openapi:' rather than '<'
- Check the chained YAMLError for line/column of the syntax problem
Example fix
# before: file contains '<html>403 Forbidden</html>' # after: file starts with openapi: 3.1.0 info: title: Example API
Defensive patterns
Strategy: validation
Validate before calling
import json, yaml
text = Path(spec).read_text(encoding="utf-8")
try:
json.loads(text)
except json.JSONDecodeError:
try:
yaml.safe_load(text)
except yaml.YAMLError as e:
raise ValueError(f"spec is not JSON/YAML: {e}") from e Try / catch
try:
spec = load_spec(path)
except SpecParseError as e:
if "not valid JSON or YAML" in str(e):
show e.__cause__ (YAMLError with line/col) and stop — the file content is wrong, retrying will not help Prevention
- curl -I the spec URL and check Content-Type/first byte before saving
- Run a YAML/JSON lint step on downloaded specs in CI
- Never trust a cached partial download; re-fetch on any parse failure
When it happens
Trigger: A spec file containing an HTML error page (proxy intercepted the download), a truncated download, binary/UTF-16 content, or JSON with a trailing comma and invalid YAML characters.
Common situations: Downloading an OpenAPI spec from a URL that returned a login page; CI caching a partial file; a Postman export saved with a BOM or wrong encoding.
Related errors
- {p} does not contain a mapping at the top level
- bad_response
- Cannot resume scan {scan_id}: agents.json is unreadable: {ex
- Invalid API spec '{target}': {exc}
- Missing Postman collection id in '{target}' (expected postma
AI-assisted analysis of usestrix/strix@8551339130 (2026-08-15).
Data as JSON: /api/errors/67120f6f20484b2f.
Report an issue: GitHub.