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
- Wait and retry later — blocks are usually temporary.
- Switch to a different browser profile / clear cookies as the message suggests.
- Use a less detectable browser setup (non-headless mode, realistic user agent).
- Change IP address or route through a residential proxy.
- 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
- Throttle searches (multi-second delays) instead of tight loops.
- Rotate browser profiles/cookies across runs.
- Prefer non-headless or stealth-configured browsers for scraping Booking.com.
- Avoid known datacenter IPs; use residential connections where possible.
- Stop and back off on the first captcha instead of hammering retries.
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
- amazon ${action} hit a robot check
- FETCH_ERROR
- Ctrip is asking for a captcha; complete it in your browser s
- hotels.ctrip.com
- vacations.ctrip.com
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/a76ac76f6b449ecc.
Report an issue: GitHub.