jackwener/OpenCLI · error · CommandExecutionError

Trip.com transfer listing did not render (state=${String(wai

Error message

Trip.com transfer listing did not render (state=${String(waitResult)}); check the city and airport code

What it means

CommandExecutionError thrown when the transfer page loaded but never reached the 'content' state (and was not 'captcha' or 'empty'). Trip.com's results area never rendered, so the message includes the observed state to debug whether it was a timeout, a redirect, or something else.

Source

Thrown at clis/trip/transfer.js:59

        'price', 'currency',
        'url',
    ],
    func: async (page, kwargs) => {
        const city = parseKeyword('city', kwargs.city);
        const airport = parseIataCode('airport', kwargs.airport);
        const limit = parseListLimit(kwargs.limit);

        const listUrl = buildTransferListUrl(city, airport);
        await page.goto(listUrl);
        const waitResult = await page.evaluate(WAIT_FOR_TRANSFERS_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 === 'empty') {
            throw new EmptyResultError('trip transfer', `No airport transfers for ${city} (${airport})`);
        }
        if (waitResult !== 'content') {
            throw new CommandExecutionError(`Trip.com transfer listing did not render (state=${String(waitResult)}); check the city and airport code`);
        }
        const landedPath = await page.evaluate('location.pathname');
        if (!/\/airport-transfers\/[^/]+\/airport-[^/]+/i.test(String(landedPath))) {
            throw new CommandExecutionError(`Trip.com bounced ${city} / ${airport} to the transfer landing; check the city name matches the airport IATA code`);
        }
        const raw = await page.evaluate(buildTransferExtractJs());
        if (!Array.isArray(raw)) {
            throw new CommandExecutionError('Trip.com transfer DOM extraction returned malformed rows');
        }
        if (raw.length === 0) {
            throw new CommandExecutionError('Trip.com transfer cards rendered but parser did not find required price anchors');
        }
        return raw.slice(0, limit).map((r, i) => ({
            rank: i + 1,
            type: r.type,
            passengers: r.passengers,
            luggage: r.luggage,
            price: r.price,

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Check the city and airport code arguments for correctness
  2. Read the state value in the message and retry if it indicates timeout
  3. Test the equivalent transfer URL in a real browser
  4. Update the WAIT_FOR_TRANSFERS_JS probe if Trip.com changed its loading markers

Example fix

// before
await getTransfers({ city: 'london heathrow', airport: 'Heathrow' });
// after
await getTransfers({ city: 'London', airport: 'LHR' });
Defensive patterns

Strategy: retry

Validate before calling

if (!/^[A-Z]{3}$/.test(airport)) throw new Error(`airport must be IATA code, got ${airport}`);
if (!city) throw new Error('city required');

Type guard

null

Try / catch

try {
  const rows = await getTransfers(args);
} catch (e) {
  if (/did not render \(state=/.test(e.message)) {
    await sleep(2000);
    return getTransfers(args); // single retry
  }
  throw e;
}

Prevention

When it happens

Trigger: Invalid or unrecognized city/airport-code combination causing Trip.com to spin or stall on the search page; slow network exceeding the wait timeout; client-side JS error on Trip.com preventing render.

Common situations: Wrong airport code format (city name instead of IATA); flaky hotel/café network; Trip.com front-end deploy introducing a runtime error; headless browser missing features the page needs.

Related errors


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