Egonex-AI/Understand-Anything · error · Error

Figma API ${path} failed: ${res.status} ${res.statusText}

Error message

Figma API ${path} failed: ${res.status} ${res.statusText}

What it means

Thrown by the private get<T> helper inside FigmaApiSource whenever fetch resolves with a non-ok HTTP status. It reports the Figma API path plus the HTTP status code and status text, covering the fetchDocument, fetchStyles, and renderImages calls. No retry or response-body inspection is performed — any 4xx/5xx is fatal.

Source

Thrown at understand-anything-plugin/packages/core/src/figma/source/api-source.ts:29

export class FigmaApiSource implements FigmaSource {
  private readonly token: string;

  constructor(private readonly fileKey: string, token: string | undefined = process.env.FIGMA_TOKEN) {
    if (!token) {
      throw new Error(
        "FIGMA_TOKEN is not set. Create a personal access token at " +
        "https://www.figma.com/settings, then run: export FIGMA_TOKEN=<token>",
      );
    }
    this.token = token;
  }

  private async get<T>(path: string): Promise<T> {
    // Token travels only in the header — never in the URL, never logged.
    const res = await fetch(`${FIGMA_API}${path}`, { headers: { "X-Figma-Token": this.token } });
    if (!res.ok) {
      throw new Error(`Figma API ${path} failed: ${res.status} ${res.statusText}`);
    }
    return (await res.json()) as T;
  }

  fetchDocument(): Promise<FigmaDocument> {
    return this.get<FigmaDocument>(`/files/${this.fileKey}`);
  }

  fetchStyles(): Promise<FigmaStyles> {
    return this.get<FigmaStyles>(`/files/${this.fileKey}/styles`);
  }

  async renderImages(nodeIds: string[]): Promise<Record<string, string>> {
    if (nodeIds.length === 0) return {};
    const ids = encodeURIComponent(nodeIds.join(","));
    const data = await this.get<{ images: Record<string, string> }>(
      `/images/${this.fileKey}?ids=${ids}&format=png&scale=1`,
    );

View on GitHub (pinned to 32944829e7)

Solutions

  1. Inspect the HTTP status in the message: 401/403 means regenerate/refresh the token and verify file permissions; 404 means re-copy the fileKey from the Figma URL.
  2. For 429, slow down and retry with exponential backoff honouring Figma's rate-limit headers.
  3. For 5xx, retry after a short delay — these are transient on Figma's side.
  4. Wrap the fetchDocument/fetchStyles/renderImages calls in a retry layer that re-reads the status and backs off only on 429/5xx.

Example fix

// before
const doc = await src.fetchDocument();
// after — surface and branch on the status
try { const doc = await src.fetchDocument(); }
catch (e) {
  const m = String(e.message).match(/failed: (\d+)/);
  if (m && m[1] === '429') { /* back off and retry */ }
  else throw e;
}
Defensive patterns

Strategy: retry

Validate before calling

// pre-check is not possible for a live network call; verify inputs instead
if (!fileKey) throw new Error('fileKey required before fetching');

Try / catch

async function fetchWithRetry<T>(fn: () => Promise<T>, retries = 3): Promise<T> {
  for (let attempt = 0; ; attempt++) {
    try { return await fn(); }
    catch (e) {
      const m = String((e as Error).message).match(/failed: (\d+)/);
      const status = m ? Number(m[1]) : 0;
      const transient = status === 429 || status >= 500;
      if (!transient || attempt >= retries) throw e;
      await new Promise(r => setTimeout(r, 2 ** attempt * 500));
    }
  }
}
const doc = await fetchWithRetry(() => src.fetchDocument());

Prevention

When it happens

Trigger: A 401/403 when the token is wrong or lacks scope; a 404 when the fileKey does not exist or the token cannot access that file; a 429 when rate limited; a 5xx on a transient Figma outage; an empty nodeIds call never reaches here (short-circuited) but renderImages with bad IDs can.

Common situations: Token valid but lacking access to the target file; stale fileKey after a file was moved/deleted; hitting Figma rate limits under heavy use; transient API errors during a Figma incident; copy-pasting a file key from a different team's file.

Related errors


AI-assisted analysis of Egonex-AI/Understand-Anything@32944829e7 (2026-08-12). Data as JSON: /api/errors/d65b3e4197453a97. Report an issue: GitHub.