jackwener/OpenCLI · warning · AuthRequiredError

Trip.com is asking for a verification; complete it in your b

Error message

Trip.com is asking for a verification; complete it in your browser session and retry

What it means

This AuthRequiredError is thrown when the train timetable page's wait script reports 'captcha', meaning Trip.com inserted a human-verification challenge instead of rendering the train list. Like the tours flow, the library requires you to solve the CAPTCHA manually in the shared browser session before scraping can continue.

Source

Thrown at clis/trip/train.js:53

    ],
    columns: [
        'rank',
        'departureTime', 'fromStation',
        'arrivalTime', 'toStation',
        'duration', 'changes',
        'url',
    ],
    func: async (page, kwargs) => {
        const from = parseKeyword('from', kwargs.from);
        const to = parseKeyword('to', kwargs.to);
        const country = parseKeyword('country', kwargs.country);
        const limit = parseListLimit(kwargs.limit);

        const searchUrl = buildTrainRouteUrl(country, from, to);
        await page.goto(searchUrl);
        const waitResult = await page.evaluate(WAIT_FOR_TRAINS_JS);
        if (waitResult === 'captcha') {
            throw new AuthRequiredError('trip.com', 'Trip.com is asking for a verification; complete it in your browser session and retry');
        }
        if (waitResult !== 'content') {
            throw new CommandExecutionError(`Trip.com train timetable did not render (state=${String(waitResult)}); check the city names and --country`);
        }
        const raw = await page.evaluate(buildTrainExtractJs());
        if (!Array.isArray(raw)) {
            throw new CommandExecutionError('Trip.com train DOM extraction returned malformed rows');
        }
        if (raw.length === 0) {
            throw new EmptyResultError('trip train', `No timetable for ${from} to ${to} (${country})`);
        }
        return raw.slice(0, limit).map((r, i) => ({
            rank: i + 1,
            departureTime: r.departureTime,
            fromStation: r.fromStation,
            arrivalTime: r.arrivalTime,
            toStation: r.toStation,
            duration: r.duration,

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Complete the CAPTCHA in the interactive browser session, then rerun the command.
  2. Throttle searches (delays between requests) and reduce batch size.
  3. Switch to a residential IP or disable VPN.
  4. Use a persistent, warmed browser profile with existing Trip.com cookies.

Example fix

// before
const r = await page.evaluate(WAIT_FOR_TRAINS_JS); // throws on captcha, aborts batch
// after
let r = await page.evaluate(WAIT_FOR_TRAINS_JS);
if (r === 'captcha') { await promptUserToSolveCaptcha(page); r = await page.evaluate(WAIT_FOR_TRAINS_JS); }
Defensive patterns

Strategy: try-catch

Type guard

function waitSaysCaptcha(r) { return r === 'captcha'; }

Try / catch

try {
  const trains = await trainSearch(country, from, to);
} catch (e) {
  if (e instanceof AuthRequiredError) {
    await pauseForHumanCaptcha(e.message);
    return trainSearch(country, from, to);
  }
  throw e;
}

Prevention

When it happens

Trigger: page.evaluate(WAIT_FOR_TRAINS_JS) returning 'captcha' for a train route search — typically triggered by automation patterns, VPN/datacenter IPs, or high query frequency on train timetables.

Common situations: Batch-queriing many train routes back-to-back; running in CI from cloud IPs; Trip.com enforcing stricter anti-bot checks on its trains vertical.

Related errors


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