heygen-com/hyperframes · error · Error

figma render returned non-SVG bytes for an svg export — retr

Error message

figma render returned non-SVG bytes for an svg export — retry the import

What it means

Thrown inside freezeAndRecord() before decoding an SVG export. It sniffs the first byte of the downloaded payload: a valid SVG starts with '<' (0x3c), an XML declaration '<?xml' (0x3f), or a UTF-8 BOM (0xef). Any other leading byte means figma did not return SVG (e.g. a PNG/JPEG binary, or an HTML/text error page), so decoding would produce U+FFFD soup that still gets written to disk. The message instructs a retry because the cause is usually transient.

Source

Thrown at packages/cli/src/commands/figma/asset.ts:133

 * times). */
async function freezeAndRecord(
  fileKey: string,
  nodeId: string,
  url: string,
  ext: FigmaAssetFormat,
  opts: AssetImportOptions,
  version: string,
  deps: AssetImportDeps,
  description: string | undefined,
  entity: string | undefined,
): Promise<AssetImportResult> {
  let bytes = await deps.download(url);
  if (ext === "svg") {
    // Sniff before decoding: an SVG starts with '<' or an XML decl/BOM. A
    // non-text payload would decode to U+FFFD soup and still write to disk.
    const b0 = bytes[0];
    if (b0 !== 0x3c && b0 !== 0x3f && b0 !== 0xef)
      throw new Error("figma render returned non-SVG bytes for an svg export — retry the import");
    bytes = new TextEncoder().encode(sanitizeSvg(new TextDecoder().decode(bytes)));
  }
  const id = nextId(deps.projectDir, "image");
  const destAbs = join(typeDirPath(deps.projectDir, "image"), `${id}.${ext}`);
  freezeBytes(bytes, destAbs);
  const record: FigmaManifestRecord = {
    id,
    type: "image",
    path: relative(deps.projectDir, destAbs),
    source: `figma:${fileKey}/${nodeId}`,
    ...(description !== undefined && { description }),
    ...(entity !== undefined && { entity }),
    provenance: {
      source: "figma",
      fileKey,
      nodeId,
      version,
      format: opts.format,

View on GitHub (pinned to c2996c8626)

Solutions

  1. Re-run the same import command — the message explicitly says 'retry the import'
  2. If it persists, switch --format to png for that node
  3. Check figma status / the node's renderability in the figma UI

Example fix

// before: transient svg render glitch
hyperframes figma asset aBcDeF:1:2 --format svg
// after: re-run, or fall back to png if it persists
hyperframes figma asset aBcDeF:1:2 --format svg   # retry once more
hyperframes figma asset aBcDeF:1:2 --format png    # if svg keeps failing
Defensive patterns

Strategy: retry

Try / catch

async function importSvgWithRetry(ref: string, opts: AssetImportOptions, deps: AssetImportDeps) {
  for (let attempt = 0; attempt < 3; attempt += 1) {
    try {
      return await runAssetImport(ref, { ...opts, format: 'svg' }, deps);
    } catch (err) {
      if (attempt === 2 || !(err instanceof Error) || !err.message.includes('non-SVG bytes')) throw err;
    }
  }
  throw new Error('svg import failed after retries');
}

Prevention

When it happens

Trigger: figma's /v1/images endpoint returned a non-SVG body for an svg-format request: a transient render glitch, an error HTML page (first byte '<' would pass though), a PNG (0x89), JPEG (0xff), or a rate-limit/auth text response. The guard specifically catches binary/HTML masquerading as SVG.

Common situations: A momentary figma render hiccup; a node too complex to export as vector so figma falls back to raster bytes; a CDN edge serving stale/wrong content-type.

Related errors


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