{"record":{"id":"22dffd20b66be01f","repo":"heygen-com/hyperframes","slug":"figma-ref-ref-filekey-has-no-nodeid","errorCode":null,"errorMessage":"figma ref ${ref.fileKey} has no nodeId","messagePattern":"figma ref (.+?) has no nodeId","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/figma/client.ts","lineNumber":172,"sourceCode":"  try {\n    text = await res.text();\n  } catch {\n    return null;\n  }\n  try {\n    const body: unknown = JSON.parse(text);\n    if (isRecord(body)) {\n      if (typeof body.err === \"string\") return body.err;\n      if (typeof body.message === \"string\") return body.message;\n    }\n  } catch {\n    // non-JSON body — fall through\n  }\n  return text.trim() === \"\" ? null : text.trim();\n}\n\nfunction requireNodeId(ref: FigmaRef): string {\n  if (!ref.nodeId) throw new Error(`figma ref ${ref.fileKey} has no nodeId`);\n  return ref.nodeId;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n  return typeof value === \"object\" && value !== null;\n}\n\nfunction optionalString(value: unknown): string | undefined {\n  return typeof value === \"string\" ? value : undefined;\n}\n\nfunction toVariablePayload(payload: unknown): FigmaVariablePayload | null {\n  if (!isRecord(payload) || typeof payload.name !== \"string\") return null;\n  return {\n    name: payload.name,\n    key: optionalString(payload.key),\n    resolvedType: optionalString(payload.resolvedType),\n    valuesByMode: isRecord(payload.valuesByMode) ? payload.valuesByMode : undefined,","sourceCodeStart":154,"sourceCodeEnd":190,"githubUrl":"https://github.com/heygen-com/hyperframes/blob/c2996c8626135db5253519359d8a063d3bafad8d/packages/core/src/figma/client.ts#L154-L190","documentation":"Thrown by the internal requireNodeId helper when a FigmaRef passed to renderNode or nodeTree has no nodeId. Those two endpoints (/v1/images and /v1/files/:key/nodes) operate on a specific node, unlike file-level calls (imageFills, variables, styles, fileVersion) which only need the fileKey. The library treats a missing nodeId as a programmer error rather than silently fetching the whole file.","triggerScenarios":"Calling client.renderNode({ fileKey: 'abc123' }) with no nodeId; calling client.nodeTree({ fileKey: 'abc123' }); parseFigmaRef returning only a fileKey because the input URL had no ?node-id= parameter and no ':node' suffix, then passing that ref to renderNode/nodeTree.","commonSituations":"User pastes a figma file URL without selecting a frame first (the URL lacks the node-id query param); a CLI flag accepts a bare fileKey but the command targets a node-rendering flow; refactoring that drops the nodeId field from a FigmaRef object literal.","solutions":["Ensure the figma URL or ref string includes a node id — in the figma UI, right-click a frame → 'Copy link' (the URL then carries ?node-id=...).","If building FigmaRef programmatically, always set nodeId: { fileKey, nodeId: '12:34' }.","Switch to a file-level call (imageFills/styles/variables) if you actually want whole-file data and don't have a node."],"exampleFix":"// before — no nodeId, renderNode cannot target a node\nawait client.renderNode({ fileKey: 'aBcDeF1234' }, { format: 'png' });\n\n// after — nodeId present (colon-form, as figma uses)\nawait client.renderNode(\n  { fileKey: 'aBcDeF1234', nodeId: '12:34' },\n  { format: 'png' },\n);","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"import type { FigmaRef } from '.../figma/types';\nexport function refHasNodeId(ref: FigmaRef): ref is FigmaRef & { nodeId: string } {\n  return typeof ref.nodeId === 'string' && ref.nodeId.length > 0;\n}\n// usage\nif (!refHasNodeId(ref)) throw new Error(`ref for ${ref.fileKey} needs a nodeId`);","tryCatchPattern":null,"preventionTips":["Always parse user input through parseFigmaRef so the nodeId is extracted from the URL's ?node-id when present.","In CLI flows that call renderNode/nodeTree, validate refHasNodeId up front and prompt the user to copy a node-level link.","Prefer the batched renderNodes/files-nodes calls when you can, and skip refs lacking nodeId."],"tags":["figma","validation","api","precondition"],"backgroundTag":null,"analyzedSha":"c2996c8626135db5253519359d8a063d3bafad8d","analyzedAt":"2026-08-12T22:18:56.877Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}