{"record":{"id":"da47ab45c66b68c5","repo":"heygen-com/hyperframes","slug":"figma-render-download-failed-http-res-status","errorCode":null,"errorMessage":"figma render download failed: HTTP ${res.status}","messagePattern":"figma render download failed: HTTP (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/commands/figma/download.ts","lineNumber":6,"sourceCode":"import { exceedsFreezeCap, MAX_FREEZE_BYTES } from \"@hyperframes/core/figma\";\n\n/** Fetch a short-lived figma CDN render url into bytes. */\nexport async function downloadRender(url: string): Promise<Uint8Array> {\n  const res = await fetch(url);\n  if (!res.ok) throw new Error(`figma render download failed: HTTP ${res.status}`);\n  // Reject oversized responses before buffering the body — the freeze cap\n  // alone only fires after the full allocation.\n  const declared = Number(res.headers.get(\"content-length\") ?? 0);\n  if (exceedsFreezeCap(declared))\n    throw new Error(\n      `figma render download failed: content-length ${declared} exceeds ${MAX_FREEZE_BYTES} cap`,\n    );\n  return new Uint8Array(await res.arrayBuffer());\n}\n","sourceCodeStart":1,"sourceCodeEnd":16,"githubUrl":"https://github.com/heygen-com/hyperframes/blob/c2996c8626135db5253519359d8a063d3bafad8d/packages/cli/src/commands/figma/download.ts#L1-L16","documentation":"Thrown by downloadRender() when the fetch of figma's short-lived CDN render url returns a non-ok status. Figma's /v1/images hands back signed CDN urls that expire within minutes; any delay or a transient CDN fault surfaces here as the raw HTTP code.","triggerScenarios":"HTTP 403/404 from an expired or already-consumed signed url (clock skew, slow disk write, or a long pause between renderNodes and downloadRender); 5xx from a CDN outage; a network redirect that resolves to an error page.","commonSituations":"The render url was obtained but the download was delayed (heavy disk I/O, slow machine); figma CDN transient error; proxy/corporate network interfering with the signed url.","solutions":["Re-run the whole import — it regenerates a fresh signed url","Retry the fetch a few times with short backoff for transient 5xx","Check system clock skew and network/proxy configuration"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"async function downloadWithRetry(url: string, attempts = 3): Promise<Uint8Array> {\n  for (let i = 0; i < attempts; i += 1) {\n    try {\n      return await downloadRender(url);\n    } catch (err) {\n      const status = (err as Error).message.match(/HTTP (\\d+)/)?.[1];\n      const code = status ? Number(status) : 0;\n      // Only retry transient codes; re-run the whole import if the url expired.\n      if (i === attempts - 1 || (code !== 0 && code < 500 && code !== 403)) throw err;\n      await new Promise(r => setTimeout(r, 500 * 2 ** i));\n    }\n  }\n  throw new Error('download failed after retries');\n}","preventionTips":["Freeze the render url immediately after renderNodes returns — signed urls expire fast","Re-run the whole import to mint a fresh url rather than reusing a stale one","Check system clock skew if 403s appear on fresh urls"],"tags":["figma","network","download","cdn","retry"],"backgroundTag":null,"analyzedSha":"c2996c8626135db5253519359d8a063d3bafad8d","analyzedAt":"2026-08-12T22:18:56.877Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}