can1357/oh-my-pi · error · SearchProviderError
Google HTML error (${page.status})
Error message
Google HTML error (${page.status}) What it means
Thrown by callGoogleHtml when the loaded page's HTTP status is outside 200–299 and the response was not already classified as a traffic challenge. The status code is included in the message and reused as the error status, indicating Google's server rejected the request in a way not covered by the specific block detectors.
Source
Thrown at packages/coding-agent/src/web/search/providers/google.ts:153
} 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(
"google",
"Google returned its JavaScript challenge instead of rendered search results.",
429,
);
}
return page.html;
}
/** Execute a Google web search with fetch-first loading and a headless-browser fallback. */
export async function searchGoogle(params: SearchParams): Promise<SearchResponse> {
const numResults = clampNumResults(params.numSearchResults ?? params.limit, DEFAULT_NUM_RESULTS, MAX_NUM_RESULTS);
const html = await callGoogleHtml(params, numResults);
const parsed = parseHtmlResults(html);
const sources: SearchSource[] = [];View on GitHub (pinned to 9690622007)
Solutions
- Check the status code in the message for the specific failure class.
- Retry — 5xx statuses are typically transient.
- Update the omp package: Google's scraping endpoint behavior changes over time and fixes ship in newer versions.
- Fall back to an API-backed search provider for reliability.
Defensive patterns
Strategy: retry
Try / catch
try {
return await search({ provider: 'google', query });
} catch (err) {
const status = err instanceof SearchProviderError ? err.statusCode : undefined;
if (status && status >= 500) return await retryWithBackoff(() => search({ provider: 'google', query }));
throw err;
} Prevention
- Retry only 5xx statuses; treat 4xx as configuration problems.
- Keep the package updated — Google endpoint behavior drifts.
- Monitor the embedded status code to alert on persistent non-2xx patterns.
When it happens
Trigger: The Google Search HTML fetch completes with a non-2xx status (e.g. 301/302 to an unresolvable redirect, 404, 5xx) while blockReason() returned undefined (not 403/429, no /sorry/ URL, no captcha markers).
Common situations: Google serving regional redirect loops or unexpected status codes; transient Google server errors; middleware/proxy rewriting the response; Google changing endpoint behavior after an update.
Related errors
- Google blocked the browser search with an automated-traffic
- Google returned its JavaScript challenge instead of rendered
- Gemini image request failed (${resp.status}): ${message}
- Anthropic API error (${response.status}): ${errorText}
- Ecosia search failed: ${message}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/d6cc429d94e6985e.
Report an issue: GitHub.