{"record":{"id":"d7f8fe2ab87b5be3","repo":"heygen-com/hyperframes","slug":"figma-asset-import-produced-no-result-for-refin","errorCode":null,"errorMessage":"figma asset import produced no result for \"${refInput}\"","messagePattern":"figma asset import produced no result for \"(.+?)\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/commands/figma/asset.ts","lineNumber":165,"sourceCode":"      source: \"figma\",\n      fileKey,\n      nodeId,\n      version,\n      format: opts.format,\n      scale: opts.scale,\n    },\n  };\n  appendRecord(deps.projectDir, record);\n  return { record, snippet: buildAssetSnippet(record), reused: false };\n}\n\nexport async function runAssetImport(\n  refInput: string,\n  opts: AssetImportOptions,\n  deps: AssetImportDeps,\n): Promise<AssetImportResult> {\n  const [result] = await runAssetImportMany([refInput], opts, deps);\n  if (!result) throw new Error(`figma asset import produced no result for \"${refInput}\"`);\n  return result;\n}\n\n/**\n * Import many nodes of ONE figma file. Cache-checks each, renders the misses\n * in a SINGLE /v1/images batch call (figma's documented rate-limit\n * workaround — N nodes, one REST request), freezes each, and regenerates\n * index.md once. Results come back in input order.\n */\nexport async function runAssetImportMany(\n  refInputs: string[],\n  opts: AssetImportOptions,\n  deps: AssetImportDeps,\n): Promise<AssetImportResult[]> {\n  if (refInputs.length === 0) return [];\n  const refs = refInputs.map(requireNodeRef);\n  const fileKey = refs[0]!.fileKey;\n  const mixed = refs.find((r) => r.fileKey !== fileKey);","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/heygen-com/hyperframes/blob/c2996c8626135db5253519359d8a063d3bafad8d/packages/cli/src/commands/figma/asset.ts#L147-L183","documentation":"Thrown by runAssetImport(), the single-ref convenience wrapper. It delegates to runAssetImportMany([refInput]) and asserts the result array is non-empty. Under the current contract runAssetImportMany always returns one slot for one input (or throws RENDER_FAILED first), so reaching this line means an internal length invariant was broken. Treat hitting it as a bug, not an expected failure mode.","triggerScenarios":"Effectively unreachable in normal flow: would require runAssetImportMany to return an empty array for a non-empty input list, which the early `if (refInputs.length === 0) return []` guard and the subsequent slots.map prevent.","commonSituations":"Only if a future refactor breaks the 1:1 input/output length contract of runAssetImportMany, or a caller passes a refInput that parseFigmaRef reduces to nothing in an unexpected way.","solutions":["Do not try to handle this in application code — report it as an internal bug","Re-run the import; if reproducible, capture the exact ref string and open an issue"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await runAssetImport(ref, opts, deps);\n} catch (err) {\n  // Defensive guard — if hit, it is an internal invariant break, not user input.\n  // Capture the ref and report rather than masking.\n  if ((err as Error).message.includes('produced no result')) {\n    console.error('internal: runAssetImport returned no result for', ref);\n  }\n  throw err;\n}","preventionTips":["Do not write fallback logic for this guard — surface it as a bug","Pin the library version so a regression in runAssetImportMany's length contract is caught"],"tags":["figma","asset","defensive","invariant"],"backgroundTag":null,"analyzedSha":"c2996c8626135db5253519359d8a063d3bafad8d","analyzedAt":"2026-08-12T22:18:56.877Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}