{"record":{"id":"1a608dc06b4c4878","repo":"jackwener/OpenCLI","slug":"trip-com-attraction-cards-rendered-but-parser-did","errorCode":null,"errorMessage":"Trip.com attraction cards rendered but parser did not find required detail-link anchors","messagePattern":"Trip\\.com attraction cards rendered but parser did not find required detail-link anchors","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/trip/attraction.js","lineNumber":61,"sourceCode":"\n        const searchUrl = buildAttractionSearchUrl(query);\n        await page.goto(searchUrl);\n        const waitResult = await page.evaluate(WAIT_FOR_ATTRACTIONS_JS);\n        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 attraction', `No attractions for \"${query}\"`);\n        }\n        if (waitResult !== 'content') {\n            throw new CommandExecutionError(`Trip.com things-to-do page did not render product cards (state=${String(waitResult)})`);\n        }\n        const raw = await page.evaluate(buildAttractionExtractJs());\n        if (!Array.isArray(raw)) {\n            throw new CommandExecutionError('Trip.com attraction DOM extraction returned malformed rows');\n        }\n        if (raw.length === 0) {\n            throw new CommandExecutionError('Trip.com attraction cards rendered but parser did not find required detail-link anchors');\n        }\n        return raw.slice(0, limit).map((r, i) => ({\n            rank: i + 1,\n            name: r.name,\n            rating: r.rating,\n            reviews: r.reviews,\n            booked: r.booked,\n            price: r.price,\n            currency: 'USD',\n            url: r.url,\n        }));\n    },\n});\n","sourceCodeStart":43,"sourceCodeEnd":75,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/trip/attraction.js#L43-L75","documentation":"This CommandExecutionError is thrown when the extraction script DID return an array but it contained zero rows — attraction cards rendered on the page, yet the parser found no `things-to-do/detail/<id>` anchors, which are the required per-row detail links. The library anchors each row on these links; without them it refuses to emit rows with missing data rather than returning partial garbage.","triggerScenarios":"Running `trip attraction` when the things-to-do page has rendered product cards but page.evaluate(buildAttractionExtractJs()) returns [] because the expected detail-link anchors (`things-to-do/detail/...`) are absent or renamed in the DOM.","commonSituations":"Trip.com A/B test or redesign replacing detail anchors with JS-only navigation; a localized page variant using different link patterns; cards rendering as skeleton placeholders that pass the wait check but lack real anchor hrefs yet.","solutions":["Retry after a short delay — skeleton placeholders may not have hydrated into real anchor links yet.","Inspect the live page and verify `a[href*='things-to-do/detail/']` anchors exist; if the pattern changed, update buildAttractionExtractJs in clis/trip/utils.js.","Force the English/international Trip.com variant (cookies/region) since localized variants may use different link markup.","Check for a library update addressing a Trip.com front-end change."],"exampleFix":"// before: assuming any rendered page yields rows\nconst rows = await runCli(['trip', 'attraction', query]);\n// after: treat parse-empty as retryable\ntry {\n  rows = await runCli(['trip', 'attraction', query]);\n} catch (e) {\n  if (/parser did not find required detail-link anchors/.test(e.message)) {\n    await sleep(5000);\n    return runCli(['trip', 'attraction', query]);\n  }\n  throw e;\n}","handlingStrategy":"retry","validationCode":"null","typeGuard":"null","tryCatchPattern":"try {\n  return await runCli(['trip', 'attraction', query]);\n} catch (e) {\n  if (/parser did not find required detail-link anchors/.test(e.message)) {\n    await sleep(5000); // skeletons may still be hydrating\n    return runCli(['trip', 'attraction', query]);\n  }\n  throw e;\n}","preventionTips":["Retry after a delay — rendered skeletons may not yet contain real detail-link anchors.","Periodically verify `a[href*='things-to-do/detail/']` still exists on Trip.com pages.","Force the international/English Trip.com variant to avoid localized markup differences.","Track library updates; this error usually signals a Trip.com front-end change."],"tags":["dom-parsing","selector-drift","empty-result","trip-com"],"backgroundTag":"dom-structure-changed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}