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
- Re-run the same import command — the message explicitly says 'retry the import'
- If it persists, switch --format to png for that node
- 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
- Treat a non-SVG-bytes error as transient — retry once or twice before changing approach
- Keep a png fallback ready for nodes that persistently fail svg export
- Log the first byte you observe if you instrument downloads, to confirm the sniff
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
- ref "${refInput}" has no node id — share a link with ?node-i
- figma asset import produced no result for "${refInput}"
- all refs in one import must share a fileKey (batch is per-fi
- RENDER_FAILED
- figma asset import produced no result for "${refInputs[i]}"
AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12).
Data as JSON: /api/errors/beed6a5bdd313216.
Report an issue: GitHub.