jackwener/OpenCLI · error · CommandExecutionError

Booking.com served a verification / captcha page; retry late

Error message

Booking.com served a verification / captcha page; retry later or change profile

What it means

This CommandExecutionError is thrown when the extractor reports raw.blocked === true, meaning Booking.com served a verification/captcha (bot-detection) page instead of search results. The library detects this state and refuses to continue, telling the user to retry later or switch the browser profile.

Source

Thrown at clis/booking/search.js:284

    } catch (_) {
      // selector wait is best-effort — extractor handles empty case explicitly
    }

    let raw;
    try {
      raw = await page.evaluate(EXTRACTOR);
    } catch (err) {
      throw new CommandExecutionError(`Failed to extract Booking.com cards: ${err?.message || err}`);
    }

    if (raw && typeof raw === 'object' && raw.data && raw.session) {
      raw = raw.data;
    }
    if (!raw || typeof raw !== 'object') {
      throw new CommandExecutionError('Booking.com page returned no extractable data');
    }
    if (raw.blocked) {
      throw new CommandExecutionError('Booking.com served a verification / captcha page; retry later or change profile');
    }

    if (raw.ok !== true) {
      throw new CommandExecutionError('Booking.com extractor returned an invalid status');
    }
    if (!Array.isArray(raw.items)) {
      throw new CommandExecutionError('Booking.com extractor returned malformed items');
    }

    const items = raw.items;
    if (items.length === 0) {
      const totalText = String(raw.totalText || '').trim();
      if (hasPositiveResultCount(totalText)) {
        throw new CommandExecutionError(
          `Booking.com page declared results but no property cards were parsed: ${totalText}`,
        );
      }
      throw new EmptyResultError(

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Wait and retry later — blocks are usually temporary.
  2. Switch to a different browser profile / clear cookies as the message suggests.
  3. Use a less detectable browser setup (non-headless mode, realistic user agent).
  4. Change IP address or route through a residential proxy.
  5. Slow down request rate between searches to avoid triggering rate-based detection.

Example fix

// before (rapid loop, same profile)
for (const d of destinations) await search(d);
// after (throttled, rotating profiles)
for (const d of destinations) { await search(d, { profile: nextProfile() }); await sleep(5000); }
Defensive patterns

Strategy: retry

Try / catch

try {
  return await booking.search(params);
} catch (e) {
  if (/verification \/ captcha/.test(e.message)) {
    await sleep(60_000);            // back off before retrying
    return booking.search({ ...params, profile: rotateProfile() });
  }
  throw e;
}

Prevention

When it happens

Trigger: The extractor's blocked flag is set because the loaded page contains Booking.com's challenge/captcha markup — headless-browser detection, too many rapid requests from one IP, or a flagged cookie/profile.

Common situations: Running many searches in a loop from one IP in CI; default headless Chromium fingerprint flagged by the anti-bot system; shared datacenter IP with poor reputation; reused profile whose cookies were marked suspicious.

Related errors


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