{"record":{"id":"b96962ead462d2f7","repo":"jackwener/OpenCLI","slug":"trip-com-transfer-cards-rendered-but-parser-did-no","errorCode":null,"errorMessage":"Trip.com transfer cards rendered but parser did not find required price anchors","messagePattern":"Trip\\.com transfer cards rendered but parser did not find required price anchors","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/trip/transfer.js","lineNumber":70,"sourceCode":"        if (waitResult === 'captcha') {\n            throw new AuthRequiredError('trip.com', 'Trip.com is asking for a verification; complete it in your browser session and retry');\n        }\n        if (waitResult === 'empty') {\n            throw new EmptyResultError('trip transfer', `No airport transfers for ${city} (${airport})`);\n        }\n        if (waitResult !== 'content') {\n            throw new CommandExecutionError(`Trip.com transfer listing did not render (state=${String(waitResult)}); check the city and airport code`);\n        }\n        const landedPath = await page.evaluate('location.pathname');\n        if (!/\\/airport-transfers\\/[^/]+\\/airport-[^/]+/i.test(String(landedPath))) {\n            throw new CommandExecutionError(`Trip.com bounced ${city} / ${airport} to the transfer landing; check the city name matches the airport IATA code`);\n        }\n        const raw = await page.evaluate(buildTransferExtractJs());\n        if (!Array.isArray(raw)) {\n            throw new CommandExecutionError('Trip.com transfer DOM extraction returned malformed rows');\n        }\n        if (raw.length === 0) {\n            throw new CommandExecutionError('Trip.com transfer cards rendered but parser did not find required price anchors');\n        }\n        return raw.slice(0, limit).map((r, i) => ({\n            rank: i + 1,\n            type: r.type,\n            passengers: r.passengers,\n            luggage: r.luggage,\n            price: r.price,\n            currency: r.currency,\n            url: listUrl,\n        }));\n    },\n});\n","sourceCodeStart":52,"sourceCodeEnd":83,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/trip/transfer.js#L52-L83","documentation":"CommandExecutionError thrown when transfer cards visibly rendered and the extractor returned an array, but the array is empty: the parser found no required price anchors inside the cards. Layout changed enough to keep card containers but break the price element the extractor depends on.","triggerScenarios":"Trip.com moves prices behind a lazy-loaded component, swaps price elements for a new component (e.g. 'from $X' badge), or gates prices behind a currency/region selection, so the extractor's price-anchor selector matches zero nodes.","commonSituations":"New Trip.com pricing UI; prices only render after interaction (hover/scroll); currency-selection interstitial; regional variant of the page without list prices.","solutions":["Inspect the rendered cards in DevTools and update the price-anchor selector in buildTransferExtractJs()","Add a scroll/interaction step to trigger lazy price rendering before extraction","Confirm the market/currency (via --country or cookies) shows list prices","Capture a screenshot/DOM snapshot on this error to speed up future selector fixes"],"exampleFix":"// before\nconst raw = await page.evaluate(buildTransferExtractJs());\n// after\nawait page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));\nawait page.waitForTimeout(1500);\nconst raw = await page.evaluate(buildTransferExtractJs());","handlingStrategy":"fallback","validationCode":"// before extraction, ensure prices had a chance to lazy-load\nawait page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));\nawait page.waitForTimeout(1500);","typeGuard":"function hasPriceAnrows(v) { return Array.isArray(v) && v.length > 0; }","tryCatchPattern":"try {\n  const rows = await getTransfers(args);\n} catch (e) {\n  if (e.message.includes('price anchors')) {\n    console.error('Prices lazy-load or UI changed; try scroll-before-extract or update selector');\n  }\n  throw e;\n}","preventionTips":["Scroll the page before extraction to trigger lazy prices","Set currency/market cookies so list prices render","Save a DOM snapshot on this error for debugging","Update the price-anchor selector whenever Trip.com refreshes its pricing UI"],"tags":["scraping","dom-parsing","trip-com","selector-drift"],"backgroundTag":"dom-extraction-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}