jackwener/OpenCLI · error · AuthRequiredError
vacations.ctrip.com
Error message
vacations.ctrip.com
What it means
AuthRequiredError thrown when the Ctrip vacations (flight+hotel package) page presents a captcha. WAIT_FOR_VACATIONS_JS returns 'captcha' and the library requires the user to solve it in their browser session before package search can proceed. Automatic retries will keep failing until the captcha is cleared.
Source
Thrown at clis/ctrip/package.js:47
{ name: 'destination', required: true, positional: true, help: 'Destination keyword (e.g. 三亚 / 北京 / 曼谷)' },
{ name: 'limit', default: 20, help: 'Number of packages (1-50)' },
],
columns: [
'rank',
'title', 'subtitle',
'tags', 'score', 'sold', 'reviews',
'price',
'url',
],
func: async (page, kwargs) => {
const destination = parsePlaceName('destination', kwargs.destination);
const limit = parseListLimit(kwargs.limit);
const searchUrl = buildPackageListUrl(destination);
await page.goto(searchUrl);
const waitResult = await page.evaluate(WAIT_FOR_VACATIONS_JS);
if (waitResult === 'captcha') {
throw new AuthRequiredError('vacations.ctrip.com', 'Ctrip is asking for a captcha; complete it in your browser session and retry');
}
if (waitResult === 'empty') {
throw new EmptyResultError('ctrip package', `No flight-plus-hotel packages for "${destination}"`);
}
if (waitResult !== 'content') {
throw new CommandExecutionError(`Ctrip package page did not render package cards (state=${String(waitResult)})`);
}
const raw = await page.evaluate(buildVacationsExtractJs());
if (!Array.isArray(raw)) {
throw new CommandExecutionError('Ctrip package DOM extraction returned malformed rows');
}
if (raw.length === 0) {
throw new CommandExecutionError('Ctrip package cards rendered but parser did not find required package anchors');
}
return raw.slice(0, limit).map((r, i) => ({
rank: i + 1,
title: r.title,
subtitle: r.subtitle,View on GitHub (pinned to 49907e53dc)
Solutions
- Solve the captcha in the interactive browser session, then re-run the command
- Re-authenticate/refresh the CLI's browser profile cookies
- Throttle request frequency and add jittered delays
- Use a residential IP or rotate network exit
Example fix
// before
await ctrip.package({ destination: '三亚' }); // throws on captcha
// after
try {
return await ctrip.package({ destination: '三亚' });
} catch (e) {
if (e instanceof AuthRequiredError) {
await promptUserToSolveCaptchaInBrowser();
return await ctrip.package({ destination: '三亚' });
}
throw e;
} Defensive patterns
Strategy: retry
Validate before calling
// cannot be validated pre-call; detect captcha state after load const state = await page.evaluate(WAIT_FOR_VACATIONS_JS); if (state === 'captcha') await requireManualCaptchaResolution();
Type guard
const isAuthRequiredError = (e) => e instanceof AuthRequiredError || e?.name === 'AuthRequiredError';
Try / catch
try {
return await ctrip.package({ destination });
} catch (e) {
if (isAuthRequiredError(e)) {
await promptUserToSolveCaptcha();
return await ctrip.package({ destination }); // retry once after manual solve
}
throw e;
} Prevention
- Warm up the session by browsing vacations.ctrip.com manually first
- Rate-limit package searches; add random delays
- Rotate IPs / avoid obvious datacenter exits
- Halt automation on repeated captcha states and alert an operator
When it happens
Trigger: page.evaluate(WAIT_FOR_VACATIONS_JS) resolves 'captcha' after page.goto(buildPackageListUrl(destination)) — anti-bot detection triggered by automation, blocked IP, or stale session cookies on vacations.ctrip.com.
Common situations: Rapid repeated package searches from a server IP; first-time access from a new region/IP; expired connect session; headless browsing fingerprint detected.
Related errors
- hotels.ctrip.com
- guazi ${contextHint} hit an anti-bot challenge — Guazi may h
- [taxonomy=selector_drift] site=powerchina command=search log
- Trip.com is asking for a verification; complete it in your b
- 请先在共享 Chrome 完成 1688 登录/验证,再重试(${action})
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/1135a36d9264cf47.
Report an issue: GitHub.