can1357/oh-my-pi · error · SearchProviderError

Firecrawl API error (${response.status}): ${errorText}

Error message

Firecrawl API error (${response.status}): ${errorText}

What it means

callFirecrawlSearch() throws this when the Firecrawl /search endpoint responds with a non-OK HTTP status that the generic classifier (classifyProviderHttpError) did not map to a more specific error. The message embeds the status code and the raw response body text, giving you the provider's own error explanation.

Source

Thrown at packages/coding-agent/src/web/search/providers/firecrawl.ts:133

): Promise<FirecrawlSearchResponse> {
	const headers: Record<string, string> = {
		"Content-Type": "application/json",
	};
	if (apiKey) {
		headers.Authorization = `Bearer ${apiKey}`;
	}
	const response = await (params.fetch ?? fetch)(resolveSearchUrl(), {
		method: "POST",
		headers,
		body: JSON.stringify(buildRequestBody(params)),
		signal: withHardTimeout(params.signal, params.timeoutMs),
	});

	if (!response.ok) {
		const errorText = await response.text();
		const classified = classifyProviderHttpError("firecrawl", response.status, errorText);
		if (classified) throw classified;
		throw new SearchProviderError(
			"firecrawl",
			`Firecrawl API error (${response.status}): ${errorText}`,
			response.status,
		);
	}

	const data = (await response.json()) as FirecrawlSearchResponse;
	if (data.success === false) {
		throw new SearchProviderError("firecrawl", data.error?.trim() || "Firecrawl request failed");
	}
	return data;
}

/** ISO `YYYY-MM-DD` to Google `MM/DD/YYYY` for `tbs=cdr` custom date ranges. */
function toGoogleDate(iso: string): string {
	const [year, month, day] = iso.split("-");
	return `${month}/${day}/${year}`;
}

View on GitHub (pinned to 9690622007)

Solutions

  1. Read the embedded status and errorText in the message: it usually states the exact cause (invalid key, quota, bad parameter)
  2. Verify FIRECRAWL_API_KEY is correct and active in the Firecrawl dashboard
  3. Check your plan credits/usage and wait out 429 rate limits with backoff
  4. Check the Firecrawl status page for outages and retry transient 5xx later
Defensive patterns

Strategy: retry

Validate before calling

// No pre-call validation possible; verify credentials ahead of time via a cheap authenticated call:
const res = await fetch(`${baseUrl}/v2/search`, { method: "POST", headers: { Authorization: `Bearer ${key}` }, body: "{}" });
if (res.status === 401 || res.status === 402) throw new Error("Firecrawl key invalid or out of credits");

Try / catch

import { SearchProviderError } from "...";
try {
  results = await firecrawlSearch(query);
} catch (err) {
  if (err instanceof SearchProviderError && err.status === 429) {
    await Bun.sleep(backoffMs); // retry with exponential backoff
  } else if (err instanceof SearchProviderError && (err.status === 401 || err.status === 403)) {
    logger.error("Firecrawl auth failed — refresh FIRECRAWL_API_KEY");
  } else throw err;
}

Prevention

When it happens

Trigger: Any non-2xx response from Firecrawl /search: 401/403 from an invalid or expired FIRECRAWL_API_KEY, 402 when out of credits, 429 rate limiting, 5xx server-side errors, or provider-side validation errors with unusual bodies that the classifier does not recognize.

Common situations: Expired or wrong API key, exhausted Firecrawl plan credits, hitting rate limits during bulk searches, or Firecrawl incident/outage.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/58d488d27d4afd40. Report an issue: GitHub.