heygen-com/hyperframes · error · HyperframesApiError
Invalid JSON response: ${(err as Error).message}
Error message
Invalid JSON response: ${(err as Error).message} What it means
Thrown by the generated cloud API client when res.text() succeeds but JSON.parse(text) throws. The error is wrapped in HyperframesApiError carrying the HTTP status, the parse error message, and the first 500 chars of the raw body, so callers can distinguish a transport/encoding problem from a genuine API error envelope.
Source
Thrown at packages/cli/src/cloud/_gen/client.ts:141
if (!res.ok) {
throw await this.toApiError(res);
}
// 204 No Content
if (res.status === 204) {
return undefined as T;
}
const text = await res.text();
if (!text) {
return undefined as T;
}
let parsed: unknown;
try {
parsed = JSON.parse(text);
} catch (err) {
throw new HyperframesApiError({
status: res.status,
message: `Invalid JSON response: ${(err as Error).message}`,
raw: text.slice(0, 500),
});
}
// The /v3 envelope is {data: T, ...}. Unwrap when present and the
// call site asked for it (the default) so consumers read the inner
// payload directly. List endpoints opt out so they can read
// ``has_more`` / ``next_token``.
const unwrap = opts.unwrapData !== false;
if (
unwrap &&
parsed &&
typeof parsed === "object" &&
"data" in (parsed as Record<string, unknown>)
) {
const envelope = parsed as { data: T };
return envelope.data;View on GitHub (pinned to c2996c8626)
Solutions
- Inspect HyperframesApiError.raw (first 500 chars) and .status — if it is HTML from a proxy/gateway, fix the network egress or base URL.
- Verify the configured API base URL / registry URL is correct and reachable with `curl -i <url>`.
- If the body has a leading BOM or junk, ensure no transforming middleware sits between the client and server.
- Retry once on 502/504-style HTML in case of a transient gateway blip, then escalate to the API owner with the raw snippet.
Example fix
try {
await client.listRenders();
} catch (err) {
if (err instanceof HyperframesApiError && err.raw?.startsWith("<")) {
// HTML body => gateway/proxy interception, not an API payload
throw new Error(`API base URL misconfigured or blocked by a proxy: ${err.raw.slice(0, 120)}`);
}
throw err;
} Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-send: sanity-check the base URL returns JSON
async function assertJsonEndpoint(baseUrl: string) {
const res = await fetch(baseUrl + '/health');
const ct = res.headers.get('content-type') ?? '';
if (!ct.includes('application/json')) {
throw new Error(`Base URL ${baseUrl} does not serve JSON (got ${ct})`);
}
} Type guard
function isHyperframesApiError(err: unknown): err is HyperframesApiError {
return err instanceof Error && err.name === 'HyperframesApiError';
} Try / catch
try {
const data = await client.listRenders();
} catch (err) {
if (err instanceof HyperframesApiError && err.raw?.startsWith('<')) {
// HTML body => wrong base URL or proxy interception
}
throw err;
} Prevention
- Pin the API base URL to a known-good host and validate reachability at startup.
- Bypass transforming proxies (corporate MITM) for the API host.
- Log HyperframesApiError.raw on JSON failures to spot gateway/HTML responses fast.
When it happens
Trigger: Any HyperframesCloudClient request whose response is not valid JSON: an HTML 502/504 from a gateway, a proxy interception page, a truncated body, a text/plain error from a misconfigured base URL, or a BOM/prefix before the JSON. A 204 or empty body is handled earlier and does not reach this branch.
Common situations: Corporate/MITM proxy injecting an HTML block page; pointing config.registry or the API base URL at the wrong host that returns HTML; transient 5xx served as HTML by a load balancer; an API version mismatch where the endpoint returns a non-JSON landing page.
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
- Failed to download ${url}: HTTP ${res.status} ${res.statusTe
- Failed to download ${url}: empty response body
- Truncated download: got ${bytes} bytes, expected ${totalOpt}
- [build-zip] npm install into staging failed (status ${result
- [validateConfig] config: Step Functions execution input is n
AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12).
Data as JSON: /api/errors/660ae51f909d28f2.
Report an issue: GitHub.