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

  1. Validate the file locally: python -c "import yaml,sys; yaml.safe_load(open(sys.argv[1]))" file
  2. Re-download the spec and confirm the content starts with '{' or 'openapi:' rather than '<'
  3. 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

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


AI-assisted analysis of usestrix/strix@8551339130 (2026-08-15). Data as JSON: /api/errors/67120f6f20484b2f. Report an issue: GitHub.