jackwener/OpenCLI · error · CommandExecutionError

google images is blocked by a Google CAPTCHA/consent/interst

Error message

google images is blocked by a Google CAPTCHA/consent/interstitial page.

What it means

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.

Source

Thrown at clis/google/images.js:446

        const limit = requireBoundedInteger(args.limit, 20, 1, 100, '--limit');
        const resolveOriginal = args.resolve !== false;
        const lang = encodeURIComponent(String(args.lang || 'en'));
        const pageSize = Math.max(limit, 20);
        const url = `https://www.google.com/search?tbm=isch&q=${encodeURIComponent(query)}&hl=${lang}&num=${pageSize}`;

        await runBrowserStep('google images navigation', () => navigateGoogleImages(page, url));
        try {
            await page.wait({ selector: '#rso img, #islrg img, #center_col img, #rcnt img', timeout: 8 });
        }
        catch {
            await page.wait(2).catch(() => {});
        }

        const rows = await runBrowserStep('google images extraction', () => evaluateGoogleImageRows(page, limit, resolveOriginal));
        if (rows.length === 0) {
            const state = await runBrowserStep('google images page-state inspection', () => evaluateGoogleImagesPageState(page));
            if (state.captchaOrConsent) {
                throw new CommandExecutionError('google images is blocked by a Google CAPTCHA/consent/interstitial page.');
            }
            if (!state.explicitNoResults) {
                throw new CommandExecutionError('google images returned no extractable result rows; the page layout may have changed.');
            }
        }
        return normalizeImageRows(rows, query, limit);
    },
});

export const __test__ = { command, evaluateGoogleImageRows, extractGoogleImageRows, inspectGoogleImagesPage, normalizeImageRows, navigateGoogleImages };

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Solve the CAPTCHA or accept the consent page in a visible (non-headless) browser session once so cookies persist, then retry the command
  2. Rotate IP address or use a residential proxy, since datacenter IPs are commonly CAPTCHA-challenged by Google
  3. Slow down request rate / add delays between queries to avoid bot detection
  4. Update the scraper if Google changed its consent-page markers, so evaluateGoogleImagesPageState still detects the state correctly

Example fix

// before
rows = await evaluateGoogleImageRows(page, limit, resolveOriginal); // 0 rows on CAPTCHA
// after
await page.waitForTimeout(2000);
rows = await evaluateGoogleImageRows(page, limit, resolveOriginal);
if (rows.length === 0) await acceptConsentOrSolveCaptcha(page); // clear interstitial before retrying
Defensive patterns

Strategy: retry

Validate before calling

// no pre-call validation possible for Google's bot detection;
// ensure session cookies exist and IP is residential before invoking
function canAttempt() { return !!process.env.GOOGLE_COOKIES; }

Type guard

function isBlockedState(state) {
  return typeof state === 'object' && state !== null && state.captchaOrConsent === true;
}

Try / catch

try {
  const images = await imagesCommand.func(args);
} catch (e) {
  if (e.message.includes('CAPTCHA')) {
    await rotateProxy();
    return imagesCommand.func(args); // retry once after IP rotation
  }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/f50da842e5c6efef. Report an issue: GitHub.