jackwener/OpenCLI · error · CommandExecutionError

Trip.com train timetable did not render (state=${String(wait

Error message

Trip.com train timetable did not render (state=${String(waitResult)}); check the city names and --country

What it means

CommandExecutionError thrown when the Trip.com trains page was loaded but the timetable never reached a renderable state. The page.evaluate(WAIT_FOR_TRAINS_JS) probe returns a state string; anything other than 'content' (and other than 'captcha') means the results container never appeared. The state value is embedded in the message so you can see what the page actually did.

Source

Thrown at clis/trip/train.js:56

        '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,
            changes: r.changes,
            url: searchUrl,
        }));

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Check the city names passed via --from/--to and correct spelling; Trip.com needs its own city naming
  2. Pass or correct --country so the search runs in the right Trip.com market
  3. Retry once — transient slowness can make the wait probe time out
  4. Read the state value in the message; if it is a timeout, increase patience/retry; if it is a layout-related state, update WAIT_FOR_TRAINS_JS selectors
  5. Open the searchUrl in a browser to confirm the route exists on Trip.com

Example fix

// before
await runTripTrain({ from: 'Londn', to: 'Paris', country: 'UK' });
// after
await runTripTrain({ from: 'London', to: 'Paris', country: 'GB' });
Defensive patterns

Strategy: retry

Validate before calling

// pre-check inputs
if (!from || !to) throw new Error('from/to required');
const known = ['london','paris','rome','madrid']; // your own allowlist
if (!known.includes(from.toLowerCase())) console.warn(`verify '${from}' exists on trip.com trains`);

Type guard

function isWaitState(v) { return v === 'content' || v === 'captcha' || typeof v === 'string'; }

Try / catch

try {
  const rows = await getTripTrains(args);
} catch (e) {
  if (/did not render \(state=(\w+)\)/.test(e.message)) {
    const state = e.message.match(/state=(\w+)/)[1];
    if (state === 'timeout') return retryOnce(args);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling the trip train command with a from/to pair that Trip.com does not recognize (misspelled city, city not served by rail, or wrong --country), or the site layout/timing changed so the wait probe times out with 'timeout' or a similar non-content state.

Common situations: Typos in city names ('Londonn'), passing a city that only has an airport transfer service, omitting or mistyping --country so the URL resolves to a market without that route, slow page load exceeding the internal wait timeout, or Trip.com A/B redesigns breaking the wait selector.

Related errors


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