{"record":{"id":"d6cc429d94e6985e","repo":"can1357/oh-my-pi","slug":"google-html-error-page-status","errorCode":null,"errorMessage":"Google HTML error (${page.status})","messagePattern":"Google HTML error \\((.+?)\\)","errorType":"exception","errorClass":"SearchProviderError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/web/search/providers/google.ts","lineNumber":153,"sourceCode":"\t} catch (error) {\n\t\tif (error instanceof SearchProviderError || params.signal?.aborted) throw error;\n\t\tif (signal.aborted) {\n\t\t\tthrow new SearchProviderError(\"google\", \"Google browser search timed out.\", 504);\n\t\t}\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tthrow new SearchProviderError(\"google\", `Google browser search failed: ${message}`, 503);\n\t}\n\n\tconst blocked = blockReason(page);\n\tif (blocked === \"traffic\") {\n\t\tthrow new SearchProviderError(\n\t\t\t\"google\",\n\t\t\t\"Google blocked the browser search with an automated-traffic challenge. Try another web search provider or retry later.\",\n\t\t\t429,\n\t\t);\n\t}\n\tif (page.status < 200 || page.status >= 300) {\n\t\tthrow new SearchProviderError(\"google\", `Google HTML error (${page.status})`, page.status);\n\t}\n\tif (blocked === \"javascript\") {\n\t\tthrow new SearchProviderError(\n\t\t\t\"google\",\n\t\t\t\"Google returned its JavaScript challenge instead of rendered search results.\",\n\t\t\t429,\n\t\t);\n\t}\n\treturn page.html;\n}\n\n/** Execute a Google web search with fetch-first loading and a headless-browser fallback. */\nexport async function searchGoogle(params: SearchParams): Promise<SearchResponse> {\n\tconst numResults = clampNumResults(params.numSearchResults ?? params.limit, DEFAULT_NUM_RESULTS, MAX_NUM_RESULTS);\n\tconst html = await callGoogleHtml(params, numResults);\n\tconst parsed = parseHtmlResults(html);\n\n\tconst sources: SearchSource[] = [];","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/web/search/providers/google.ts#L135-L171","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  return await search({ provider: 'google', query });\n} catch (err) {\n  const status = err instanceof SearchProviderError ? err.statusCode : undefined;\n  if (status && status >= 500) return await retryWithBackoff(() => search({ provider: 'google', query }));\n  throw err;\n}","preventionTips":["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."],"tags":["http","google","scraping","search-provider"],"backgroundTag":"http-5xx","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}