can1357/oh-my-pi · error · SearchProviderError

Google browser search timed out.

Error message

Google browser search timed out.

What it means

Thrown by callGoogleHtml when the headless-browser fetch of Google Search results does not complete before the hard timeout: the timeout AbortSignal fired and the underlying error was not already a SearchProviderError or an externally-aborted caller signal. It is wrapped with status 504 to signal an upstream/gateway timeout.

Source

Thrown at packages/coding-agent/src/web/search/providers/google.ts:138

	const signal = withHardTimeout(params.signal, params.timeoutMs);
	const url = buildSearchUrl(params, numResults);
	let page: LoadedHtmlPage;
	try {
		page = await browserFetch(url, {
			fetch: params.fetch,
			signal,
			timeoutMs: params.timeoutMs,
			referer: GOOGLE_HOME_URL,
			browser: {
				homeUrl: GOOGLE_HOME_URL,
				ready: { selector: "a h3", timeoutMs: RESULT_RENDER_TIMEOUT_MS },
				shouldFallback: candidate => blockReason(candidate) !== undefined,
			},
		});
	} catch (error) {
		if (error instanceof SearchProviderError || params.signal?.aborted) throw error;
		if (signal.aborted) {
			throw new SearchProviderError("google", "Google browser search timed out.", 504);
		}
		const message = error instanceof Error ? error.message : String(error);
		throw new SearchProviderError("google", `Google browser search failed: ${message}`, 503);
	}

	const blocked = blockReason(page);
	if (blocked === "traffic") {
		throw new SearchProviderError(
			"google",
			"Google blocked the browser search with an automated-traffic challenge. Try another web search provider or retry later.",
			429,
		);
	}
	if (page.status < 200 || page.status >= 300) {
		throw new SearchProviderError("google", `Google HTML error (${page.status})`, page.status);
	}
	if (blocked === "javascript") {
		throw new SearchProviderError(

View on GitHub (pinned to 9690622007)

Solutions

  1. Increase the search timeoutMs parameter (and any caller deadline).
  2. Retry the search — slow renders are often transient.
  3. Switch to a different web search provider (Jina, Gemini) if Google scraping remains too slow in your environment.
  4. Check machine load / headless browser availability (browser fallback) and network latency to google.com.

Example fix

// before
await search({ provider: "google", query, timeoutMs: 3000 });
// after
await search({ provider: "google", query, timeoutMs: 15000 });
Defensive patterns

Strategy: retry

Type guard

function isGoogleTimeout(e: unknown): boolean {
  return e instanceof SearchProviderError && e.provider === 'google' && e.statusCode === 504;
}

Try / catch

try {
  return await search({ provider: 'google', query, timeoutMs: 15000 });
} catch (err) {
  if (isGoogleTimeout(err)) return await search({ provider: 'google', query, timeoutMs: 30000 });
  throw err;
}

Prevention

When it happens

Trigger: browserFetch(url) (fetch-first with headless-browser fallback, waiting for the `a h3` result selector within RESULT_RENDER_TIMEOUT_MS) exceeds params.timeoutMs; the merged signal aborts and `signal.aborted` is true while the caller's own signal is not.

Common situations: Slow or resource-starved machine where the headless browser cannot render results in time; heavily throttled network; very low timeoutMs configured; Google serving a slow challenge page that never renders result anchors.

Understand the failure class

Related errors


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