can1357/oh-my-pi · error · SearchProviderError

Firecrawl request failed

Error message

Firecrawl request failed

What it means

After a successful HTTP response, callFirecrawlSearch() parses the JSON body; Firecrawl wraps results in a payload with a `success` boolean. When `success === false` and no more specific error was already raised, this generic fallback is thrown using the body's `error` field, or the literal 'Firecrawl request failed' if the error field is empty/missing.

Source

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

		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}`;
}

/**
 * Map explicit `before:`/`after:` bounds to a Firecrawl `tbs` custom date
 * range (`cdr:1,cd_min:MM/DD/YYYY,cd_max:MM/DD/YYYY`), or undefined when the
 * query carries no absolute date bounds.
 */
function buildDateTbs(parsed: StructuredQuery): string | undefined {
	if (!parsed.after && !parsed.before) return undefined;
	const parts = ["cdr:1"];

View on GitHub (pinned to 9690622007)

Solutions

  1. If the message contains provider detail from data.error, follow that specific guidance; if it is the bare fallback, enable request logging to capture the full response body
  2. Retry the search — transient provider-side failures often succeed on a second attempt
  3. Check Firecrawl status/dashboards for degraded service
  4. Verify the API key and plan still permit search (some failures surface as success:false with HTTP 200)
Defensive patterns

Strategy: retry

Validate before calling

// Validate the response envelope yourself before trusting it:
function isSuccessfulFirecrawlPayload(data: unknown): data is { success: true; data: unknown[] } {
  return typeof data === "object" && data !== null && (data as { success?: unknown }).success === true;
}

Type guard

function isFirecrawlSuccess(data: FirecrawlSearchResponse): data is FirecrawlSearchResponse & { success: true } {
  return data.success !== false;
}

Try / catch

try {
  results = await firecrawlSearch(query);
} catch (err) {
  if (err instanceof SearchProviderError && !err.status && err.message === "Firecrawl request failed") {
    // HTTP 200 but provider-side failure — retry once, then surface
    results = await firecrawlSearch(query).catch(() => fallbackSearch(query));
  } else throw err;
}

Prevention

When it happens

Trigger: Firecrawl returned HTTP 200 but the JSON body has success:false — e.g. partial processing failures, the search completed at the HTTP layer but the provider-side job failed, or a proxy/gateway returned 200 with an error-shaped JSON.

Common situations: Firecrawl accepting the request but failing during search execution (upstream engine errors), a reverse proxy masking a backend failure with a 200 status, or a response whose error text is empty so only the fallback message appears.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


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