jackwener/OpenCLI · error · CommandExecutionError

Trip.com flight page did not render flight cards (state=${St

Error message

Trip.com flight page did not render flight cards (state=${String(waitResult)})

What it means

This CommandExecutionError from clis/trip/flight.js is thrown when WAIT_FOR_FLIGHTS_JS returns anything other than 'content' (and not 'captcha'), meaning the Trip.com flight page loaded but never reached a state with rendered flight cards. The message includes the observed state string to help diagnose what the waiter saw. It indicates a page-load/render/timing problem rather than empty results or a CAPTCHA.

Source

Thrown at clis/trip/flight.js:60

        'url',
    ],
    func: async (page, kwargs) => {
        const fromCode = parseIataCode('from', kwargs.from);
        const toCode = parseIataCode('to', kwargs.to);
        if (fromCode === toCode) {
            throw new ArgumentError(`--from and --to must differ (got ${fromCode})`);
        }
        const date = parseIsoDate('date', kwargs.date);
        const limit = parseListLimit(kwargs.limit);

        const searchUrl = buildFlightSearchUrl(fromCode, toCode, date);
        await page.goto(searchUrl);
        const waitResult = await page.evaluate(WAIT_FOR_FLIGHTS_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 flight page did not render flight cards (state=${String(waitResult)})`);
        }
        const raw = await page.evaluate(buildFlightExtractJs());
        if (!Array.isArray(raw)) {
            const reason = raw && typeof raw === 'object' && typeof raw.error === 'string'
                && /^malformed flight card \d+: [a-z /]+$/.test(raw.error)
                ? `: ${raw.error}`
                : '';
            throw new CommandExecutionError(`Trip.com flight DOM extraction returned malformed rows${reason}`);
        }
        if (raw.length === 0) {
            throw new EmptyResultError('trip flight', `No flights for ${fromCode} to ${toCode} on ${date}`);
        }
        return raw.slice(0, limit).map((r, i) => ({
            rank: i + 1,
            airline: r.airline,
            departureTime: r.departureTime,
            departureAirport: r.departureAirport,
            arrivalTime: r.arrivalTime,

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Read the state value in the message and rerun with a longer wait timeout if it indicates a timeout.
  2. Open the same search URL in a visible browser to check whether flight cards render at all.
  3. Update WAIT_FOR_FLIGHTS_JS selectors if Trip.com changed its DOM structure.
  4. Retry later or from a different network/region if the page loads incompletely.

Example fix

// before
await page.goto(url);
const r = await page.evaluate(WAIT_FOR_FLIGHTS_JS); // 'timeout' -> CommandExecutionError
// after
await page.goto(url, { waitUntil: 'networkidle2' });
const r = await page.evaluate(WAIT_FOR_FLIGHTS_JS);
if (r !== 'content') {
  await page.waitForSelector(FLIGHT_CARD_SELECTOR, { timeout: 30000 }).catch(() => {});
  r = await page.evaluate(WAIT_FOR_FLIGHTS_JS);
}
Defensive patterns

Strategy: retry

Validate before calling

// Confirm the search URL is well-formed before invoking:
if (!/^https:\/\/\S*trip\.com\/.+/.test(buildFlightSearchUrl(from, to, date))) throw new Error('unexpected search URL');
if (isNaN(new Date(date))) throw new Error('date must be ISO');

Type guard

const isCommandExecutionError = (e) => e instanceof CommandExecutionError;

Try / catch

try {
  await runTripFlight(args);
} catch (e) {
  if (isCommandExecutionError(e) && /state=timeout/.test(e.message)) {
    await sleep(5000);
    return runTripFlightWithLongerTimeout(args, 30000); // one bounded retry
  }
  throw e; // non-timeout states (layout changes) need a fix, not a retry
}

Prevention

When it happens

Trigger: page.evaluate(WAIT_FOR_FLIGHTS_JS) after page.goto(searchUrl) returns e.g. 'timeout', 'error', or any non-'content' value, with no CAPTCHA detected.

Common situations: Slow network or throttled page load exceeding the waiter's timeout; Trip.com layout change breaking the flight-card selector; JavaScript disabled or failing in the headless browser; regional redirects to pages the waiter does not recognize.

Related errors


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