can1357/oh-my-pi · error · SearchProviderError
Google blocked the browser search with an automated-traffic
Error message
Google blocked the browser search with an automated-traffic challenge. Try another web search provider or retry later.
What it means
Thrown by callGoogleHtml after the page loads when blockReason() classifies the response as an automated-traffic challenge — status 403/429, a /sorry/ redirect URL, or HTML containing 'unusual traffic' / g-recaptcha markers. Status 429 signals rate limiting/abuse detection by Google against the scraping approach.
Source
Thrown at packages/coding-agent/src/web/search/providers/google.ts:146
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(
"google",
"Google returned its JavaScript challenge instead of rendered search results.",
429,
);
}
return page.html;
}
View on GitHub (pinned to 9690622007)
Solutions
- Retry later, ideally with backoff; the block is usually time-limited.
- Configure a different web search provider (Jina, Gemini, Exa, etc.) which uses APIs rather than scraping.
- Change network egress (residential IP, different VPN/exit node) if the IP is flagged.
- Reduce search frequency/concurrency to stay under Google's abuse thresholds.
Example fix
// before: tight loop against google scraping
for (const q of queries) await search({ provider: "google", query: q });
// after: fall back to an API-backed provider
const provider = pickProvider(); // e.g. "jina" when google is blocked
for (const q of queries) await search({ provider, query: q }); Defensive patterns
Strategy: fallback
Type guard
function isTrafficBlocked(e: unknown): boolean {
return e instanceof SearchProviderError && e.provider === 'google' && e.statusCode === 429;
} Try / catch
try {
return await search({ provider: 'google', query });
} catch (err) {
if (isTrafficBlocked(err)) return await search({ provider: 'jina', query }); // API-backed fallback
throw err;
} Prevention
- Throttle and queue Google scraping searches; avoid parallel bursts.
- Avoid datacenter/VPN egress IPs that Google flags.
- Treat 429 as non-retryable short-term; back off minutes, not seconds.
- Prefer API-backed providers for production workloads.
When it happens
Trigger: GET of the Google Search results URL returns status 403 or 429, redirects to a google.com/sorry/ page, or its HTML matches /unusual traffic|detected unusual traffic|g-recaptcha/i (including via the browser fallback's shouldFallback probe).
Common situations: High search volume from one IP (shared CI runners, corporate NAT, VPN endpoints); datacenter IPs Google distrusts; no cookies/captcha tokens available for the headless browser.
Related errors
- Google returned its JavaScript challenge instead of rendered
- Google HTML error (${page.status})
- DuckDuckGo HTML error (${page.status})
- DuckDuckGo blocked the request with a bot-detection challeng
- Ecosia search failed: ${message}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/caaa3c7bf217d3b7.
Report an issue: GitHub.