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 Trip.com serves a CAPTCHA/verification challenge instead of tour results. Browser-automation-driven scraping trips Trip.com's bot detection, and the library cannot proceed until a human solves the challenge in the shared browser session.

Source

Thrown at clis/trip/tour.js:59

        'rank',
        'name', 'type',
        'rating', 'reviews',
        'price', 'currency',
        'url',
    ],
    func: async (page, kwargs) => {
        const query = parseKeyword('query', kwargs.query);
        const tourType = parseTourType(kwargs.type);
        const limit = parseListLimit(kwargs.limit);

        const searchUrl = buildTourSearchUrl(query, tourType);
        await page.goto(searchUrl);
        const result = await page.evaluate(buildTourSearchJs(query));
        if (!result || typeof result !== 'object') {
            throw new CommandExecutionError('Trip.com tour search returned malformed data');
        }
        if (result.status === 'captcha') {
            throw new AuthRequiredError('trip.com', 'Trip.com is asking for a verification; complete it in your browser session and retry');
        }
        if (result.status === 'empty') {
            throw new EmptyResultError('trip tour', `No ${kwargs.type || 'private'} tours for "${query}"`);
        }
        if (result.status !== 'content') {
            throw new CommandExecutionError(`Trip.com tour search did not return results (state=${String(result.status)})`);
        }
        // Products captured but none carry a name is drift (schema moved), not an empty search;
        // a genuine no-match resolves as status 'empty' above off the page's "0 routes found".
        const rows = Array.isArray(result.rows) ? result.rows.filter((r) => r.name) : [];
        if (rows.length === 0) {
            throw new CommandExecutionError('Trip.com tour search captured products but none carried a name (the product markup may have changed)');
        }
        return rows.slice(0, limit).map((r, i) => ({
            rank: i + 1,
            name: r.name,
            type: r.type,
            rating: r.rating,

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Open the browser session interactively, complete the CAPTCHA, then rerun the command — cookies carry over.
  2. Slow down: add delays between searches and reduce request volume.
  3. Run from a residential IP or disable VPN/datacenter egress.
  4. Rebuild the browser session with a warmed, logged-in profile so bot checks are less aggressive.

Example fix

// before
for (const q of queries) await searchTours(q); // rapid loop -> captcha
// after
for (const q of queries) {
  await searchTours(q).catch(e => { if (e.name === 'AuthRequiredError') pauseForHumanVerification(); else throw e; });
  await sleep(5000);
}
Defensive patterns

Strategy: try-catch

Type guard

function isCaptchaResult(r) { return r != null && typeof r === 'object' && r.status === 'captcha'; }

Try / catch

try {
  const rows = await tourSearch(query, type);
} catch (e) {
  if (e instanceof AuthRequiredError) {
    await openBrowserForManualVerification(e.message); // user solves CAPTCHA
    return tourSearch(query, type);
  }
  throw e;
}

Prevention

When it happens

Trigger: The tour search page's evaluate reports result.status === 'captcha' — typically after rapid repeated searches, from datacenter IPs/VPNs, or with a browser session lacking prior cookies.

Common situations: Scripting many tour queries in quick succession; running from cloud CI with an unwarmed browser profile; Trip.com tightening anti-bot rules for your region/IP.

Related errors


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