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
- Increase the search timeoutMs parameter (and any caller deadline).
- Retry the search — slow renders are often transient.
- Switch to a different web search provider (Jina, Gemini) if Google scraping remains too slow in your environment.
- 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
- Set timeoutMs generously (>=10s) for scraping-based providers.
- Run on hosts with enough CPU/memory for headless-browser rendering.
- Implement one retry with a larger timeout on 504.
- Keep a non-scraping provider as fallback for latency-sensitive paths.
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
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Google browser search failed: ${message}
- Timed out waiting for CDP endpoint ${cdpUrl}${lastStatus !==
- tab.waitForResponse() timed out after ${timeoutMs}ms
- Ecosia search timed out.
- timed out: {command}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/d1bd0c4def7aa3ab.
Report an issue: GitHub.