{"record":{"id":"7ee47f6718085bb8","repo":"jackwener/OpenCLI","slug":"ctrip-round-trip-flight-cards-rendered-but-parser","errorCode":null,"errorMessage":"Ctrip round-trip flight cards rendered but parser did not find required flight anchors","messagePattern":"Ctrip round-trip flight cards rendered but parser did not find required flight anchors","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/ctrip/flight-round.js","lineNumber":96,"sourceCode":"        const searchUrl =\n            `https://flights.ctrip.com/online/list/round-${fromCode.toLowerCase()}-${toCode.toLowerCase()}` +\n            `?depdate=${depart}_${ret}&cabin=Y_S_C_F&adult=1&child=0&infant=0`;\n        await page.goto(searchUrl);\n        const waitResult = await page.evaluate(WAIT_FOR_FLIGHTS_ROUND_JS);\n        if (waitResult === 'captcha') {\n            throw new AuthRequiredError('flights.ctrip.com', 'Ctrip is asking for a captcha; complete it in your browser session and retry');\n        }\n        if (waitResult !== 'content') {\n            throw new CommandExecutionError(`Ctrip round-trip flight page did not render flight cards (state=${String(waitResult)})`);\n        }\n        const renderedCardCount = await page.evaluate(buildScrollUntilJs(ROUND_CARD_SELECTOR, limit));\n        const raw = await page.evaluate(buildFlightExtractJs(ROUND_CARD_SELECTOR, false));\n        if (!Array.isArray(raw)) {\n            throw new CommandExecutionError('Ctrip round-trip flight DOM extraction returned malformed rows');\n        }\n        if (raw.length === 0) {\n            if (Number(renderedCardCount) > 0) {\n                throw new CommandExecutionError('Ctrip round-trip flight cards rendered but parser did not find required flight anchors');\n            }\n            throw new EmptyResultError('ctrip flight-round', `No round-trip flights for ${fromCode}→${toCode} on ${depart} / ${ret}`);\n        }\n        const completeRows = raw\n            .filter((r) => r.departureTime && r.departureAirport && r.arrivalTime && r.arrivalAirport && r.airline)\n            .slice(0, limit)\n            .map((r, i) => ({\n                rank: i + 1,\n                airline: r.airline,\n                flightNo: r.flightNo,\n                aircraft: r.aircraft,\n                departureTime: r.departureTime,\n                departureAirport: r.departureAirport,\n                arrivalTime: r.arrivalTime,\n                arrivalAirport: r.arrivalAirport,\n                terminal: r.terminal,\n                price: r.price,\n                currency: r.currency,","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/ctrip/flight-round.js#L78-L114","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Upgrade the library — this signature means a selector/anchor update is likely needed.","Retry later in case an A/B variant was serving a different layout.","Inspect the rendered cards in DevTools and report which anchors are missing to maintainers.","Force a consistent locale/variant by reusing a logged-in browser profile where the standard layout renders."],"exampleFix":"// before\nnpm ls && cli flight-round ...  # old broken version\n// after\nnpm update opencli && cli flight-round --from PEK --to SHA --depart ... --return ...","handlingStrategy":"retry","validationCode":null,"typeGuard":"function isAnchorParseFailure(e) { return e && String(e.message || '').includes('did not find required flight anchors'); }","tryCatchPattern":"try { return await runFlightRound(args); }\ncatch (e) {\n  if (isAnchorParseFailure(e)) { const fresh = await newBrowserSession(); return await runFlightRound(args, fresh); }\n  throw e;\n}","preventionTips":["Upgrade the library — card internals likely changed upstream.","Retry later; A/B variants can serve different layouts intermittently.","Use a standard logged-in profile to reduce non-standard card variants.","Report missing anchors to maintainers with a DevTools screenshot."],"tags":["scraping","dom-extraction","selector-drift","ctrip","parser"],"backgroundTag":"dom-parser-drift","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}