heygen-com/hyperframes · error · Error

freeze failed: content-length ${declared} exceeds ${MAX_FREE

Error message

freeze failed: content-length ${declared} exceeds ${MAX_FREEZE_BYTES} cap

What it means

Thrown by freezeUrl before downloading the body, when the response's content-length header advertises a size larger than MAX_FREEZE_BYTES (256 MiB). This is the pre-download half of the size cap: it aborts a huge transfer early so the process never buffers hundreds of megabytes, complementing the post-download check in freezeBytes. A declared length of 0 (header absent) is treated as 'unknown' and allowed through to the freezeBytes check, so this throw only fires on an explicit oversized declaration.

Source

Thrown at packages/core/src/figma/freeze.ts:57

  let parsed: URL;
  try {
    parsed = new URL(url);
  } catch {
    return false;
  }
  if (parsed.protocol !== "https:") return false;
  const host = parsed.hostname;
  return host === "figma.com" || host.endsWith(".figma.com") || host.endsWith(".amazonaws.com");
}

export async function freezeUrl(url: string, destPath: string): Promise<number> {
  if (!isAllowedFreezeUrl(url))
    throw new Error(`freeze failed: refusing non-figma url ${url} (https + figma hosts only)`);
  const res = await fetch(url);
  if (!res.ok) throw new Error(`freeze failed: HTTP ${res.status}`);
  const declared = Number(res.headers.get("content-length") ?? 0);
  if (exceedsFreezeCap(declared))
    throw new Error(`freeze failed: content-length ${declared} exceeds ${MAX_FREEZE_BYTES} cap`);
  return freezeBytes(new Uint8Array(await res.arrayBuffer()), destPath);
}

export function freezeLocalFile(srcPath: string, destPath: string): void {
  const size = statSync(srcPath).size;
  if (exceedsFreezeCap(size))
    throw new Error(`freeze failed: ${size} bytes exceeds ${MAX_FREEZE_BYTES} cap`);
  mkdirSync(dirname(destPath), { recursive: true });
  copyFileSync(srcPath, destPath);
}

View on GitHub (pinned to c2996c8626)

Solutions

  1. Re-render at a lower scale (opts.scale) to shrink the asset below the cap.
  2. Export the asset from figma at a smaller size before importing.
  3. Confirm the content-length is genuine and not a proxy reporting a wrong value.
  4. If the asset legitimately must be huge, raise MAX_FREEZE_BYTES in a fork after reviewing disk budget.

Example fix

// before — 4x scale produces a >256 MiB PNG
await client.renderNode(ref, { format: 'png', scale: 4 });

// after — 2x scale stays under the cap
await client.renderNode(ref, { format: 'png', scale: 2 });
Defensive patterns

Strategy: validation

Validate before calling

import { exceedsFreezeCap } from '.../figma/freeze';
export function assertDeclaredUnderCap(declared: number): void {
  if (exceedsFreezeCap(declared)) {
    throw new Error(`declared size ${declared} exceeds cap — shrink the source asset`);
  }
}
// usage right after the fetch
const declared = Number(res.headers.get('content-length') ?? 0);
assertDeclaredUnderCap(declared);
await freezeUrl(url, dest);

Try / catch

try {
  await freezeUrl(url, dest);
} catch (err) {
  if (err instanceof Error && /content-length .* exceeds/.test(err.message)) {
    // re-render at lower scale
  } else throw err;
}

Prevention

When it happens

Trigger: A figma render URL whose content-length header reports > 256 MiB; a video asset exported from figma larger than the cap; a server mis-reporting content-length (rare).

Common situations: Importing a 4x-scale PNG of a very large frame; freezing a figma-exported video; a figma file with oversized embedded media.

Related errors


AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12). Data as JSON: /api/errors/61b358a1a9820a5b. Report an issue: GitHub.