jackwener/OpenCLI · error · CommandExecutionError

Ctrip round-trip flight cards rendered but parser did not fi

Error message

Ctrip round-trip flight cards rendered but parser did not find required flight anchors

What it means

A CommandExecutionError thrown when the page DID render the expected number of flight cards (renderedCardCount > 0) but the extraction script still produced an empty rows array — i.e. the parser's required flight anchors were not found inside the rendered cards. This is a targeted parser/selector mismatch signal, not an absence of data.

Source

Thrown at clis/ctrip/flight-round.js:96

        const searchUrl =
            `https://flights.ctrip.com/online/list/round-${fromCode.toLowerCase()}-${toCode.toLowerCase()}` +
            `?depdate=${depart}_${ret}&cabin=Y_S_C_F&adult=1&child=0&infant=0`;
        await page.goto(searchUrl);
        const waitResult = await page.evaluate(WAIT_FOR_FLIGHTS_ROUND_JS);
        if (waitResult === 'captcha') {
            throw new AuthRequiredError('flights.ctrip.com', 'Ctrip is asking for a captcha; complete it in your browser session and retry');
        }
        if (waitResult !== 'content') {
            throw new CommandExecutionError(`Ctrip round-trip flight page did not render flight cards (state=${String(waitResult)})`);
        }
        const renderedCardCount = await page.evaluate(buildScrollUntilJs(ROUND_CARD_SELECTOR, limit));
        const raw = await page.evaluate(buildFlightExtractJs(ROUND_CARD_SELECTOR, false));
        if (!Array.isArray(raw)) {
            throw new CommandExecutionError('Ctrip round-trip flight DOM extraction returned malformed rows');
        }
        if (raw.length === 0) {
            if (Number(renderedCardCount) > 0) {
                throw new CommandExecutionError('Ctrip round-trip flight cards rendered but parser did not find required flight anchors');
            }
            throw new EmptyResultError('ctrip flight-round', `No round-trip flights for ${fromCode}→${toCode} on ${depart} / ${ret}`);
        }
        const completeRows = raw
            .filter((r) => r.departureTime && r.departureAirport && r.arrivalTime && r.arrivalAirport && r.airline)
            .slice(0, limit)
            .map((r, i) => ({
                rank: i + 1,
                airline: r.airline,
                flightNo: r.flightNo,
                aircraft: r.aircraft,
                departureTime: r.departureTime,
                departureAirport: r.departureAirport,
                arrivalTime: r.arrivalTime,
                arrivalAirport: r.arrivalAirport,
                terminal: r.terminal,
                price: r.price,
                currency: r.currency,

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Upgrade the library — this signature means a selector/anchor update is likely needed.
  2. Retry later in case an A/B variant was serving a different layout.
  3. Inspect the rendered cards in DevTools and report which anchors are missing to maintainers.
  4. Force a consistent locale/variant by reusing a logged-in browser profile where the standard layout renders.

Example fix

// before
npm ls && cli flight-round ...  # old broken version
// after
npm update opencli && cli flight-round --from PEK --to SHA --depart ... --return ...
Defensive patterns

Strategy: retry

Type guard

function isAnchorParseFailure(e) { return e && String(e.message || '').includes('did not find required flight anchors'); }

Try / catch

try { return await runFlightRound(args); }
catch (e) {
  if (isAnchorParseFailure(e)) { const fresh = await newBrowserSession(); return await runFlightRound(args, fresh); }
  throw e;
}

Prevention

When it happens

Trigger: buildScrollUntilJs confirms ROUND_CARD_SELECTOR matched rendered cards on the round-trip page, but buildFlightExtractJs returns [] because the anchor fields it looks for inside each card are missing or renamed.

Common situations: Ctrip redesigned card internals (class names, data attributes) while keeping the card selector valid; A/B test variant serving a different card layout; lazy-rendered inner fields not present at extraction time.

Related errors


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