{"record":{"id":"660ae51f909d28f2","repo":"heygen-com/hyperframes","slug":"invalid-json-response-err-as-error-message","errorCode":null,"errorMessage":"Invalid JSON response: ${(err as Error).message}","messagePattern":"Invalid JSON response: (.+?)","errorType":"http","errorClass":"HyperframesApiError","httpStatus":null,"severity":"error","filePath":"packages/cli/src/cloud/_gen/client.ts","lineNumber":141,"sourceCode":"\n    if (!res.ok) {\n      throw await this.toApiError(res);\n    }\n\n    // 204 No Content\n    if (res.status === 204) {\n      return undefined as T;\n    }\n\n    const text = await res.text();\n    if (!text) {\n      return undefined as T;\n    }\n    let parsed: unknown;\n    try {\n      parsed = JSON.parse(text);\n    } catch (err) {\n      throw new HyperframesApiError({\n        status: res.status,\n        message: `Invalid JSON response: ${(err as Error).message}`,\n        raw: text.slice(0, 500),\n      });\n    }\n    // The /v3 envelope is {data: T, ...}. Unwrap when present and the\n    // call site asked for it (the default) so consumers read the inner\n    // payload directly. List endpoints opt out so they can read\n    // ``has_more`` / ``next_token``.\n    const unwrap = opts.unwrapData !== false;\n    if (\n      unwrap &&\n      parsed &&\n      typeof parsed === \"object\" &&\n      \"data\" in (parsed as Record<string, unknown>)\n    ) {\n      const envelope = parsed as { data: T };\n      return envelope.data;","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/heygen-com/hyperframes/blob/c2996c8626135db5253519359d8a063d3bafad8d/packages/cli/src/cloud/_gen/client.ts#L123-L159","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"try {\n  await client.listRenders();\n} catch (err) {\n  if (err instanceof HyperframesApiError && err.raw?.startsWith(\"<\")) {\n    // HTML body => gateway/proxy interception, not an API payload\n    throw new Error(`API base URL misconfigured or blocked by a proxy: ${err.raw.slice(0, 120)}`);\n  }\n  throw err;\n}","handlingStrategy":"try-catch","validationCode":"// Pre-send: sanity-check the base URL returns JSON\nasync function assertJsonEndpoint(baseUrl: string) {\n  const res = await fetch(baseUrl + '/health');\n  const ct = res.headers.get('content-type') ?? '';\n  if (!ct.includes('application/json')) {\n    throw new Error(`Base URL ${baseUrl} does not serve JSON (got ${ct})`);\n  }\n}","typeGuard":"function isHyperframesApiError(err: unknown): err is HyperframesApiError {\n  return err instanceof Error && err.name === 'HyperframesApiError';\n}","tryCatchPattern":"try {\n  const data = await client.listRenders();\n} catch (err) {\n  if (err instanceof HyperframesApiError && err.raw?.startsWith('<')) {\n    // HTML body => wrong base URL or proxy interception\n  }\n  throw err;\n}","preventionTips":["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."],"tags":["api-client","network","json","cloud"],"backgroundTag":null,"analyzedSha":"c2996c8626135db5253519359d8a063d3bafad8d","analyzedAt":"2026-08-12T22:18:56.877Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}