firecrawl/open-lovable · error · Error

Firecrawl API returned ${firecrawlResponse.status}

Error message

Firecrawl API returned ${firecrawlResponse.status}

What it means

Thrown when the Firecrawl v2 scrape endpoint responds with a non-2xx HTTP status. The response body (error text from Firecrawl) is logged to the server console, and the route raises this error so the caller knows brand extraction failed upstream.

Source

Thrown at app/api/extract-brand-styles/route.ts:37

    console.log('[extract-brand-styles] Calling Firecrawl branding API for:', url);

    const firecrawlResponse = await fetch('https://api.firecrawl.dev/v2/scrape', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${FIRECRAWL_API_KEY}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        url: url,
        formats: ['branding'],
      }),
    });

    if (!firecrawlResponse.ok) {
      const errorText = await firecrawlResponse.text();
      console.error('[extract-brand-styles] Firecrawl API error:', firecrawlResponse.status, errorText);
      throw new Error(`Firecrawl API returned ${firecrawlResponse.status}`);
    }

    const firecrawlData = await firecrawlResponse.json();
    console.log('[extract-brand-styles] Firecrawl response received successfully');

    // Extract branding data from response
    const brandingData = firecrawlData.data?.branding || firecrawlData.branding;

    if (!brandingData) {
      console.error('[extract-brand-styles] No branding data in Firecrawl response');
      console.log('[extract-brand-styles] Response structure:', JSON.stringify(firecrawlData, null, 2));
      throw new Error('No branding data in Firecrawl response');
    }

    console.log('[extract-brand-styles] Successfully extracted branding data');

    // Return the branding data
    return NextResponse.json({

View on GitHub (pinned to 69bd93bae7)

Solutions

  1. Read the server console log '[extract-brand-styles] Firecrawl API error' — the status and Firecrawl's error text identify the cause
  2. 401/403: verify FIRECRAWL_API_KEY is valid and active on firecrawl.dev
  3. 402/429: check plan credits and rate limits; upgrade or wait and retry
  4. Include the response body in the thrown message to make client-side debugging easier

Example fix

// before
throw new Error(`Firecrawl API returned ${firecrawlResponse.status}`);
// after
const errorText = await firecrawlResponse.text();
if (firecrawlResponse.status === 429) {
  throw new Error('Firecrawl rate limit exceeded, retry later');
}
throw new Error(`Firecrawl API returned ${firecrawlResponse.status}: ${errorText.slice(0, 200)}`);
Defensive patterns

Strategy: retry

Validate before calling

const url = new URL(userUrl);
if (!/^https?:$/.test(url.protocol)) throw new Error('Only http(s) URLs can be scraped');

Type guard

function isOk(res: Response): boolean { return res.status >= 200 && res.status < 300; }

Try / catch

try {
  return await extractBrandStyles(url);
} catch (e) {
  if (/returned (429|5\d\d)/.test(e.message)) {
    await sleep(2000);
    return extractBrandStyles(url); // retry transient failures once
  }
  if (/returned 40[13]/.test(e.message)) {
    throw new Error('Check FIRECRAWL_API_KEY — Firecrawl rejected authentication');
  }
  throw e;
}

Prevention

When it happens

Trigger: POST /api/extract-brand-styles with a request that Firecrawl rejects: invalid or expired API key (401), rate limit / quota exceeded (402/429), malformed URL (400), or Firecrawl outage (5xx).

Common situations: Free-tier credits exhausted; a URL that requires JS rendering beyond plan limits; temporarily down api.firecrawl.dev; sending an unreachable or private-network URL.

Related errors


AI-assisted analysis of firecrawl/open-lovable@69bd93bae7 (2026-08-28). Data as JSON: /api/errors/52deb8d1234c9c8f. Report an issue: GitHub.