heygen-com/hyperframes · error · Error
freeze failed: empty bytes
Error message
freeze failed: empty bytes
What it means
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.
Source
Thrown at packages/core/src/figma/freeze.ts:17
/**
* "Freeze" = write asset bytes to local disk permanently so renders never
* re-fetch from figma (design spec §5) — not Object.freeze.
*/
import { copyFileSync, mkdirSync, rmSync, statSync, writeFileSync } from "node:fs";
import { dirname } from "node:path";
// ponytail: bound the write so a hostile/runaway source can't fill the disk.
export const MAX_FREEZE_BYTES = 256 * 1024 * 1024;
export function exceedsFreezeCap(byteLength: number): boolean {
return byteLength > MAX_FREEZE_BYTES;
}
export function freezeBytes(bytes: Uint8Array, destPath: string): number {
if (bytes.length === 0) throw new Error("freeze failed: empty bytes");
if (exceedsFreezeCap(bytes.length))
throw new Error(`freeze failed: ${bytes.length} bytes exceeds ${MAX_FREEZE_BYTES} cap`);
mkdirSync(dirname(destPath), { recursive: true });
// Exclusive create; on EEXIST remove and retry — never write through an
// existing file or planted symlink (CodeQL js/insecure-temporary-file).
try {
writeFileSync(destPath, bytes, { flag: "wx" });
} catch (err) {
if ((err as NodeJS.ErrnoException).code !== "EEXIST") throw err;
rmSync(destPath);
writeFileSync(destPath, bytes, { flag: "wx" });
}
return bytes.length;
}
/**
* Only figma-owned hosts may be frozen from a URL — render/CDN responses
* come from figma.com subdomains or figma's S3 buckets. Blocks SSRF via aView on GitHub (pinned to c2996c8626)
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.
Example fix
// before — passes whatever arrayBuffer returns, even if empty
await freezeBytes(new Uint8Array(await res.arrayBuffer()), dest);
// after — guard the empty case with a descriptive upstream error
const buf = new Uint8Array(await res.arrayBuffer());
if (buf.length === 0) throw new Error(`empty download from ${url}`);
await freezeBytes(buf, dest); Defensive patterns
Strategy: validation
Validate before calling
export function assertNonEmpty(bytes: Uint8Array): void {
if (bytes.length === 0) throw new Error('received empty payload — upstream download produced 0 bytes');
}
// call before freezeBytes
assertNonEmpty(buf);
await freezeBytes(buf, dest); Try / catch
try {
await freezeBytes(buf, dest);
} catch (err) {
if (err instanceof Error && /empty bytes/.test(err.message)) {
// re-fetch the source, or skip this asset
} else throw err;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- freeze failed: ${bytes.length} bytes exceeds ${MAX_FREEZE_BY
- freeze failed: content-length ${declared} exceeds ${MAX_FREE
- freeze failed: refusing non-figma url ${url} (https + figma
- freeze failed: HTTP ${res.status}
- freeze failed: ${size} bytes exceeds ${MAX_FREEZE_BYTES} cap
AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12).
Data as JSON: /api/errors/8d0201b59e4d826c.
Report an issue: GitHub.