jackwener/OpenCLI · error · CommandExecutionError

Trip.com attraction cards rendered but parser did not find r

Error message

Trip.com attraction cards rendered but parser did not find required detail-link anchors

What it means

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.

Source

Thrown at clis/trip/attraction.js:61

        const searchUrl = buildAttractionSearchUrl(query);
        await page.goto(searchUrl);
        const waitResult = await page.evaluate(WAIT_FOR_ATTRACTIONS_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 === 'empty') {
            throw new EmptyResultError('trip attraction', `No attractions for "${query}"`);
        }
        if (waitResult !== 'content') {
            throw new CommandExecutionError(`Trip.com things-to-do page did not render product cards (state=${String(waitResult)})`);
        }
        const raw = await page.evaluate(buildAttractionExtractJs());
        if (!Array.isArray(raw)) {
            throw new CommandExecutionError('Trip.com attraction DOM extraction returned malformed rows');
        }
        if (raw.length === 0) {
            throw new CommandExecutionError('Trip.com attraction cards rendered but parser did not find required detail-link anchors');
        }
        return raw.slice(0, limit).map((r, i) => ({
            rank: i + 1,
            name: r.name,
            rating: r.rating,
            reviews: r.reviews,
            booked: r.booked,
            price: r.price,
            currency: 'USD',
            url: r.url,
        }));
    },
});

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Retry after a short delay — skeleton placeholders may not have hydrated into real anchor links yet.
  2. 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.
  3. Force the English/international Trip.com variant (cookies/region) since localized variants may use different link markup.
  4. Check for a library update addressing a Trip.com front-end change.

Example fix

// before: assuming any rendered page yields rows
const rows = await runCli(['trip', 'attraction', query]);
// after: treat parse-empty as retryable
try {
  rows = await runCli(['trip', 'attraction', query]);
} catch (e) {
  if (/parser did not find required detail-link anchors/.test(e.message)) {
    await sleep(5000);
    return runCli(['trip', 'attraction', query]);
  }
  throw e;
}
Defensive patterns

Strategy: retry

Validate before calling

null

Type guard

null

Try / catch

try {
  return await runCli(['trip', 'attraction', query]);
} catch (e) {
  if (/parser did not find required detail-link anchors/.test(e.message)) {
    await sleep(5000); // skeletons may still be hydrating
    return runCli(['trip', 'attraction', query]);
  }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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