{"record":{"id":"8d0201b59e4d826c","repo":"heygen-com/hyperframes","slug":"freeze-failed-empty-bytes","errorCode":null,"errorMessage":"freeze failed: empty bytes","messagePattern":"freeze failed: empty bytes","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/figma/freeze.ts","lineNumber":17,"sourceCode":"/**\n * \"Freeze\" = write asset bytes to local disk permanently so renders never\n * re-fetch from figma (design spec §5) — not Object.freeze.\n */\n\nimport { copyFileSync, mkdirSync, rmSync, statSync, writeFileSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\n\n// ponytail: bound the write so a hostile/runaway source can't fill the disk.\nexport const MAX_FREEZE_BYTES = 256 * 1024 * 1024;\n\nexport function exceedsFreezeCap(byteLength: number): boolean {\n  return byteLength > MAX_FREEZE_BYTES;\n}\n\nexport function freezeBytes(bytes: Uint8Array, destPath: string): number {\n  if (bytes.length === 0) throw new Error(\"freeze failed: empty bytes\");\n  if (exceedsFreezeCap(bytes.length))\n    throw new Error(`freeze failed: ${bytes.length} bytes exceeds ${MAX_FREEZE_BYTES} cap`);\n  mkdirSync(dirname(destPath), { recursive: true });\n  // Exclusive create; on EEXIST remove and retry — never write through an\n  // existing file or planted symlink (CodeQL js/insecure-temporary-file).\n  try {\n    writeFileSync(destPath, bytes, { flag: \"wx\" });\n  } catch (err) {\n    if ((err as NodeJS.ErrnoException).code !== \"EEXIST\") throw err;\n    rmSync(destPath);\n    writeFileSync(destPath, bytes, { flag: \"wx\" });\n  }\n  return bytes.length;\n}\n\n/**\n * Only figma-owned hosts may be frozen from a URL — render/CDN responses\n * come from figma.com subdomains or figma's S3 buckets. Blocks SSRF via a","sourceCodeStart":1,"sourceCodeEnd":35,"githubUrl":"https://github.com/heygen-com/hyperframes/blob/c2996c8626135db5253519359d8a063d3bafad8d/packages/core/src/figma/freeze.ts#L1-L35","documentation":"Thrown by freezeBytes when bytes.length === 0. freezeBytes is the low-level writer that persists downloaded or supplied asset bytes to disk so renders never re-fetch from figma; an empty payload means there is nothing to persist and almost certainly indicates an upstream bug (an empty download, a figma CDN glitch, or a caller passing an empty Uint8Array). Rejecting it here prevents a zero-byte file from being written and later treated as a valid frozen asset.","triggerScenarios":"freezeUrl downloading a 200 response with an empty body; a caller building a Uint8Array from a failed arrayBuffer() that resolved to nothing; freezeBytes called directly with new Uint8Array(0); a figma image fill whose CDN URL returns empty content.","commonSituations":"A transient CDN issue returning an empty 200; a code path that allocates a buffer but never fills it; an upstream fetch whose res.arrayBuffer() returned 0 bytes due to a network reset mid-stream.","solutions":["Re-fetch the source — empty bytes from a figma CDN URL are usually transient.","Check the caller: log res.headers and res.status before calling freezeBytes to confirm the download actually had a body.","If you genuinely may receive empty payloads, guard before calling: if (bytes.length === 0) skip or throw a clearer upstream error."],"exampleFix":"// before — passes whatever arrayBuffer returns, even if empty\nawait freezeBytes(new Uint8Array(await res.arrayBuffer()), dest);\n\n// after — guard the empty case with a descriptive upstream error\nconst buf = new Uint8Array(await res.arrayBuffer());\nif (buf.length === 0) throw new Error(`empty download from ${url}`);\nawait freezeBytes(buf, dest);","handlingStrategy":"validation","validationCode":"export function assertNonEmpty(bytes: Uint8Array): void {\n  if (bytes.length === 0) throw new Error('received empty payload — upstream download produced 0 bytes');\n}\n// call before freezeBytes\nassertNonEmpty(buf);\nawait freezeBytes(buf, dest);","typeGuard":null,"tryCatchPattern":"try {\n  await freezeBytes(buf, dest);\n} catch (err) {\n  if (err instanceof Error && /empty bytes/.test(err.message)) {\n    // re-fetch the source, or skip this asset\n  } else throw err;\n}","preventionTips":["Always check res.status and res.headers.get('content-length') before freezing a download.","Re-render the figma asset if the download came back empty — it's usually transient.","Don't allocate a Uint8Array(n) and forget to fill it."],"tags":["figma","freeze","validation","assets"],"backgroundTag":null,"analyzedSha":"c2996c8626135db5253519359d8a063d3bafad8d","analyzedAt":"2026-08-12T22:18:56.877Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}