usestrix/strix · error · SpecParseError
Postman API returned non-JSON for {label}
Error message
Postman API returned non-JSON for {label} What it means
SpecParseError raised when the Postman API returns HTTP 200 but the body is not valid JSON — response.json() raises ValueError, which is chained. Rare on Postman's side; usually caused by an intermediary (proxy, captive portal) rewriting the response.
Source
Thrown at strix/utils/api_spec.py:269
url,
headers={"X-Api-Key": api_key, "Accept": "application/json"},
timeout=_POSTMAN_FETCH_TIMEOUT,
)
except requests.RequestException as exc:
raise SpecParseError(f"Failed to reach the Postman API: {exc}") from exc
if response.status_code == 401:
raise SpecParseError("Postman API rejected the key (401). Check POSTMAN_API_KEY.")
if response.status_code == 404:
raise SpecParseError(
f"Postman {label} not found (404). Check the id and that the key can access it.",
)
if response.status_code != 200:
raise SpecParseError(f"Postman API returned HTTP {response.status_code} for {label}.")
try:
payload = response.json()
except ValueError as exc:
raise SpecParseError(f"Postman API returned non-JSON for {label}") from exc
if not isinstance(payload, dict):
raise SpecParseError(f"Unexpected Postman API response shape for {label}")
return payload
def fetch_postman_collection(collection_uid: str, api_key: str) -> dict[str, Any]:
"""Fetch a collection from the Postman API and return the raw collection dict.
Uses ``GET /collections/{uid}`` with the ``X-Api-Key`` header. The endpoint
wraps the collection under a ``collection`` key, unwrapped here so the result
matches an exported collection file.
"""
payload = _postman_api_json(
f"{POSTMAN_API_BASE}/collections/{collection_uid}",
api_key,
f"collection {collection_uid}",
)
collection = payload.get("collection", payload)View on GitHub (pinned to 8551339130)
Solutions
- Inspect what actually arrives: curl -sH "X-Api-Key: $K" https://api.getpostman.com/me | head
- Bypass or configure the proxy correctly (trust the proxy CA, disable content rewriting for api.getpostman.com)
- Fall back to a manual export downloaded from the Postman app
Example fix
# before: proxied env mangles the body # after: pin direct egress for the API host export NO_PROXY=api.getpostman.com export HTTPS_PROXY=""
Defensive patterns
Strategy: try-catch
Validate before calling
resp = requests.get(url, headers={"X-Api-Key": key}, timeout=30)
try:
resp.json()
except ValueError:
raise ValueError(f"non-JSON body ({resp.headers.get('Content-Type')}): {resp.text[:120]!r}") Try / catch
except SpecParseError as e:
if "returned non-JSON" in str(e):
dump resp.text via e.__cause__ context, check proxy/captive portal config, then retry once after fixing the network path Prevention
- Trust the corporate proxy CA bundle (REQUESTS_CA_BUNDLE) instead of disabling verification
- Exclude api.getpostman.com from content-rewriting proxies (NO_PROXY)
- Smoke-test with curl before wiring into automation
When it happens
Trigger: A transparent proxy returning an HTML login page with 200; a captive portal on conference/hotel Wi-Fi; response compression mishandled by a middleware.
Common situations: Corporate proxies intercepting HTTPS with content rewriting; misconfigured local mitmproxy; CDN/edge corruption.
Related errors
- Failed to reach the Postman API: {exc}
- unavailable
- Invalid API spec '{target}': {exc}
- Missing Postman collection id in '{target}' (expected postma
- Invalid Caido URL: {base_url}
AI-assisted analysis of usestrix/strix@8551339130 (2026-08-15).
Data as JSON: /api/errors/d265d73677cd41e5.
Report an issue: GitHub.