jackwener/OpenCLI · error · AuthRequiredError
Ctrip flight API returned HTTP ${status}; complete any verif
Error message
Ctrip flight API returned HTTP ${status}; complete any verification in the browser and retry What it means
This AuthRequiredError is thrown when a captured Ctrip batchSearch response comes back with HTTP 401 or 403, meaning flights.ctrip.com rejected the request as unauthenticated or forbidden. The library drives a real browser and captures the API response via CDP; Ctrip's risk-control layer (login state, device fingerprint, anti-bot checks) decides who may call the endpoint, so a 401/403 means the session needs human verification rather than a code fix. The library throws this instead of a generic error so callers know to complete any CAPTCHA/verification in the browser and retry.
Source
Thrown at clis/ctrip/flight.js:69
function cabinLabel(value) {
const labels = { Y: '经济舱', S: '超级经济舱', C: '公务舱', F: '头等舱' };
const codes = [...new Set(cleanString(value).toUpperCase().match(/[YSCF]/g) || [])];
return codes.length > 0 ? codes.map((code) => labels[code]).join('/') : (cleanString(value) || null);
}
function parseBatchSearchCaptures(entries) {
if (!Array.isArray(entries)) {
throw new CommandExecutionError('Ctrip flight network capture returned malformed entries');
}
const captured = entries.filter((entry) => String(entry?.url || '').includes(CAPTURE_PATTERN));
if (captured.length === 0) return null;
const byId = new Map();
let finished = false;
for (const entry of captured) {
const status = Number(entry?.responseStatus || 0);
if (status === 401 || status === 403) {
throw new AuthRequiredError('flights.ctrip.com', `Ctrip flight API returned HTTP ${status}; complete any verification in the browser and retry`);
}
if (status !== 200) {
throw new CommandExecutionError(`Ctrip flight API returned HTTP ${status || 'unknown'}`);
}
if (entry?.responseBodyTruncated === true) {
throw new CommandExecutionError('Ctrip flight API response exceeded the browser capture limit');
}
if (typeof entry?.responsePreview !== 'string') {
throw new CommandExecutionError('Ctrip flight API response body was unavailable');
}
let payload;
try {
payload = JSON.parse(entry.responsePreview);
}
catch {
throw new CommandExecutionError('Ctrip flight API returned invalid JSON');
}
if (payload?.status !== 0) {View on GitHub (pinned to 49907e53dc)
Solutions
- Open the browser session used by the CLI, complete any CAPTCHA or login/verification prompt on flights.ctrip.com, then re-run the itineraries command.
- Re-authenticate (log into Ctrip in the automation browser) so the session has valid credentials before retrying.
- Slow down request rate or rotate to a residential IP if Ctrip risk control keeps blocking the session.
- Catch AuthRequiredError in your wrapper and surface an interactive-retry step to the user instead of auto-retrying.
Example fix
// before: blind retry loop
while (tries--) { await cli.itineraries(args); }
// after: catch auth error and prompt for human verification
try {
const rows = await cli.itineraries(args);
} catch (err) {
if (err instanceof AuthRequiredError) {
console.error('Complete verification in the browser, then rerun.');
await promptUserToVerifyBrowser(); // then retry once
} else throw err;
} Defensive patterns
Strategy: try-catch
Try / catch
try {
const rows = await cli.itineraries(args);
} catch (err) {
if (err instanceof AuthRequiredError) {
// surface to user: open browser, complete CAPTCHA/login on flights.ctrip.com, retry once
await interactiveVerifyAndRetry();
} else { throw err; }
} Prevention
- Keep a logged-in, warmed-up Ctrip session in the automation browser.
- Complete any in-page verification promptly; do not let challenges linger.
- Rate-limit searches and avoid datacenter IPs to stay under risk-control thresholds.
- Catch AuthRequiredError explicitly and implement a human-in-the-loop retry.
When it happens
Trigger: Any itineraries search run where the captured /international/search/api/search/batchSearch response has responseStatus 401 or 403 — e.g. an expired or missing Ctrip login session, a flagged bot-like session, or Ctrip's risk control serving a challenge that the automated flow did not complete.
Common situations: Running the CLI after long gaps so the Ctrip session cookie expired; headless-browser fingerprints tripping Ctrip's anti-bot; running from datacenter IPs or high request volume; the in-page CAPTCHA (验证码/安全验证) appearing mid-flow.
Related errors
- 请先在共享 Chrome 完成 1688 登录/验证,再重试(${action})
- Ctrip is asking for a captcha; complete it in your browser s
- Ctrip is asking for a captcha; complete it in your browser s
- Ctrip is asking for a captcha; complete it in your browser s
- hotels.ctrip.com
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/dc383247c73413f1.
Report an issue: GitHub.