{"record":{"id":"f50da842e5c6efef","repo":"jackwener/OpenCLI","slug":"google-images-is-blocked-by-a-google-captcha-conse","errorCode":null,"errorMessage":"google images is blocked by a Google CAPTCHA/consent/interstitial page.","messagePattern":"google images is blocked by a Google CAPTCHA/consent/interstitial page\\.","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/google/images.js","lineNumber":446,"sourceCode":"        const limit = requireBoundedInteger(args.limit, 20, 1, 100, '--limit');\n        const resolveOriginal = args.resolve !== false;\n        const lang = encodeURIComponent(String(args.lang || 'en'));\n        const pageSize = Math.max(limit, 20);\n        const url = `https://www.google.com/search?tbm=isch&q=${encodeURIComponent(query)}&hl=${lang}&num=${pageSize}`;\n\n        await runBrowserStep('google images navigation', () => navigateGoogleImages(page, url));\n        try {\n            await page.wait({ selector: '#rso img, #islrg img, #center_col img, #rcnt img', timeout: 8 });\n        }\n        catch {\n            await page.wait(2).catch(() => {});\n        }\n\n        const rows = await runBrowserStep('google images extraction', () => evaluateGoogleImageRows(page, limit, resolveOriginal));\n        if (rows.length === 0) {\n            const state = await runBrowserStep('google images page-state inspection', () => evaluateGoogleImagesPageState(page));\n            if (state.captchaOrConsent) {\n                throw new CommandExecutionError('google images is blocked by a Google CAPTCHA/consent/interstitial page.');\n            }\n            if (!state.explicitNoResults) {\n                throw new CommandExecutionError('google images returned no extractable result rows; the page layout may have changed.');\n            }\n        }\n        return normalizeImageRows(rows, query, limit);\n    },\n});\n\nexport const __test__ = { command, evaluateGoogleImageRows, extractGoogleImageRows, inspectGoogleImagesPage, normalizeImageRows, navigateGoogleImages };\n","sourceCodeStart":428,"sourceCodeEnd":457,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/google/images.js#L428-L457","documentation":"This error is thrown by the google images CLI command when a headless-browser scrape of Google Images lands on a CAPTCHA, consent, or other interstitial page instead of actual results. The command evaluates the page state via evaluateGoogleImagesPageState after extracting zero rows; if state.captchaOrConsent is true, it raises this CommandExecutionError to signal that Google blocked the automated request rather than that results are missing.","triggerScenarios":"Running the google images command when Google serves a CAPTCHA/sorry page, an EU cookie-consent interstitial, or a similar blocking page before results can be evaluated, i.e. whenever evaluateGoogleImageRows returns zero rows AND the inspected page state reports captchaOrConsent.","commonSituations":"Scraping from datacenter/VPN IPs that Google flags as bot traffic; running many image queries in rapid succession from the same session; first-run headless browsers with no stored consent cookies hitting the EU consent wall; Google A/B-testing a new interstitial layout.","solutions":["Solve the CAPTCHA or accept the consent page in a visible (non-headless) browser session once so cookies persist, then retry the command","Rotate IP address or use a residential proxy, since datacenter IPs are commonly CAPTCHA-challenged by Google","Slow down request rate / add delays between queries to avoid bot detection","Update the scraper if Google changed its consent-page markers, so evaluateGoogleImagesPageState still detects the state correctly"],"exampleFix":"// before\nrows = await evaluateGoogleImageRows(page, limit, resolveOriginal); // 0 rows on CAPTCHA\n// after\nawait page.waitForTimeout(2000);\nrows = await evaluateGoogleImageRows(page, limit, resolveOriginal);\nif (rows.length === 0) await acceptConsentOrSolveCaptcha(page); // clear interstitial before retrying","handlingStrategy":"retry","validationCode":"// no pre-call validation possible for Google's bot detection;\n// ensure session cookies exist and IP is residential before invoking\nfunction canAttempt() { return !!process.env.GOOGLE_COOKIES; }","typeGuard":"function isBlockedState(state) {\n  return typeof state === 'object' && state !== null && state.captchaOrConsent === true;\n}","tryCatchPattern":"try {\n  const images = await imagesCommand.func(args);\n} catch (e) {\n  if (e.message.includes('CAPTCHA')) {\n    await rotateProxy();\n    return imagesCommand.func(args); // retry once after IP rotation\n  }\n  throw e;\n}","preventionTips":["Use residential proxies or non-datacenter IPs","Keep a persistent browser profile with accepted consent cookies","Rate-limit image queries and add randomized delays","Run headful for the first session to accept consent prompts"],"tags":["captcha","scraping","google","blocked"],"backgroundTag":"google-captcha-block","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}