{"record":{"id":"df003e1085ff4450","repo":"heygen-com/hyperframes","slug":"http-error","errorCode":"HTTP_ERROR","errorMessage":"figma request failed: HTTP ${res.status} ${path}","messagePattern":"figma request failed: HTTP (.+?) (.+?)","errorType":"error_code","errorClass":"FigmaClientError","httpStatus":null,"severity":"error","filePath":"packages/core/src/figma/client.ts","lineNumber":287,"sourceCode":"  /** Throw the typed error for a non-ok response (no-op when res.ok). */\n  async function throwForStatus(res: Response, path: string, opts: GetOptions): Promise<void> {\n    if (res.ok) return;\n    if (res.status === 401)\n      throw new FigmaClientError(\n        \"BAD_TOKEN\",\n        \"figma rejected the token (401) — it is expired or revoked. Re-mint at figma.com/settings → Security, then update FIGMA_TOKEN.\",\n        401,\n        opts.endpoint,\n      );\n    if (res.status === 403) throw forbiddenError(await readFigmaErrorMessage(res), opts);\n    if (res.status === 429)\n      throw new FigmaClientError(\n        \"RATE_LIMITED\",\n        `figma rate limit hit (429) and still limited after ${maxRetries} retries — wait a minute and re-run, or import fewer nodes per call.`,\n        429,\n        opts.endpoint,\n      );\n    throw new FigmaClientError(\n      \"HTTP_ERROR\",\n      `figma request failed: HTTP ${res.status} ${path}`,\n      res.status,\n      opts.endpoint,\n    );\n  }\n\n  async function get(path: string, opts: GetOptions): Promise<unknown> {\n    // Retry 429 with backoff before surfacing RATE_LIMITED — figma's limit is\n    // per-minute, so a couple of imports in quick succession hit it and a\n    // short wait clears it. Honor Retry-After when present, else exponential.\n    let res: Response;\n    for (let attempt = 0; ; attempt += 1) {\n      res = await doFetch(`${base}${path}`, { headers: { \"X-Figma-Token\": token } });\n      if (res.status !== 429 || attempt >= maxRetries) break;\n      const wait = retryAfterMs(res) ?? 1000 * 2 ** attempt;\n      await sleep(wait);\n    }","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/heygen-com/hyperframes/blob/c2996c8626135db5253519359d8a063d3bafad8d/packages/core/src/figma/client.ts#L269-L305","documentation":"The catch-all FigmaClientError (code HTTP_ERROR) thrown by throwForStatus for any non-ok response that is not 401, 403, or 429. It surfaces the raw status code and the request path so the developer can diagnose endpoints figma's typed mapping does not special-case — typically 404 (wrong fileKey/node path), 500/502/503 (figma outage), or 400 (malformed request the client assembled incorrectly).","triggerScenarios":"A 404 from /v1/files/<wrong-key>/nodes because the fileKey was mistyped or the file was deleted; a 500/502/503 during a figma-side incident; a 400 from a malformed query string the client built; a 405 from hitting the wrong HTTP method on a misconfigured baseUrl.","commonSituations":"Typo in the fileKey (404); pointing baseUrl at a proxy that returns non-figma status codes; figma API maintenance window (5xx); the node was deleted between a parseFigmaRef call and the nodeTree fetch.","solutions":["Read the status in the error message: 404 -> verify fileKey/nodeId exist and are shared with the token's account; 5xx -> retry after a short wait, likely a figma incident.","Double-check the fileKey has no leading/trailing whitespace or URL fragments.","If using a custom baseUrl (e.g. a proxy), confirm it forwards figma responses unchanged.","For 400s, inspect the exact path in the message and compare against figma's REST docs."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"import { FigmaClientError } from '.../figma/client';\nexport function isHttpError(err: unknown): err is FigmaClientError {\n  return err instanceof FigmaClientError && err.code === 'HTTP_ERROR';\n}","tryCatchPattern":"try {\n  await client.fileVersion(fileKey);\n} catch (err) {\n  if (isHttpError(err)) {\n    if (err.status === 404) console.error('file not found — check the fileKey');\n    else if (err.status && err.status >= 500) { /* transient, retry later */ }\n    else throw err;\n  } else throw err;\n}","preventionTips":["Validate fileKey format (alphanumeric, figma length) before the first call to surface 404s locally.","For 5xx figma outages, retry with backoff; for 4xx, surface the status to the user.","Log err.endpoint for telemetry so you can see which REST call is failing at scale."],"tags":["figma","http","network","catch-all"],"backgroundTag":null,"analyzedSha":"c2996c8626135db5253519359d8a063d3bafad8d","analyzedAt":"2026-08-12T22:18:56.877Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}