jackwener/OpenCLI · error · CommandExecutionError

Ctrip package cards rendered but parser did not find require

Error message

Ctrip package cards rendered but parser did not find required package anchors

What it means

Raised by `ctrip package` when the extraction script returned an array (well-formed) but it contains zero rows — the package cards rendered in the DOM, yet the parser found no elements matching its required package anchors (.list_product_item selectors). This distinguishes 'page loaded but markup changed' from 'page did not load'.

Source

Thrown at clis/ctrip/package.js:60

        const searchUrl = buildPackageListUrl(destination);
        await page.goto(searchUrl);
        const waitResult = await page.evaluate(WAIT_FOR_VACATIONS_JS);
        if (waitResult === 'captcha') {
            throw new AuthRequiredError('vacations.ctrip.com', 'Ctrip is asking for a captcha; complete it in your browser session and retry');
        }
        if (waitResult === 'empty') {
            throw new EmptyResultError('ctrip package', `No flight-plus-hotel packages for "${destination}"`);
        }
        if (waitResult !== 'content') {
            throw new CommandExecutionError(`Ctrip package page did not render package cards (state=${String(waitResult)})`);
        }
        const raw = await page.evaluate(buildVacationsExtractJs());
        if (!Array.isArray(raw)) {
            throw new CommandExecutionError('Ctrip package DOM extraction returned malformed rows');
        }
        if (raw.length === 0) {
            throw new CommandExecutionError('Ctrip package cards rendered but parser did not find required package anchors');
        }
        return raw.slice(0, limit).map((r, i) => ({
            rank: i + 1,
            title: r.title,
            subtitle: r.subtitle,
            tags: r.tags,
            score: r.score,
            sold: r.sold,
            reviews: r.reviews,
            price: r.price,
            url: searchUrl,
        }));
    },
});

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Verify in a browser that .list_product_item still exists on the search results page
  2. Update the CLI package to a version whose extractor matches current Ctrip markup
  3. Try a different, popular destination (e.g. 三亚) to rule out keyword-specific rendering variants
  4. Check whether results are inside an iframe and, if so, extend the extractor to query the right frame
  5. Report/patch buildVacationsExtractJs in clis/ctrip/utils.js with the new selector

Example fix

// before
if (raw.length === 0) throw new CommandExecutionError('parser did not find required package anchors');
// after
if (raw.length === 0) {
  const fallback = await page.evaluate(fallbackExtractJs()); // new selector set
  if (!fallback.length) throw new CommandExecutionError('parser did not find required package anchors');
  return fallback.slice(0, limit);
}
Defensive patterns

Strategy: fallback

Try / catch

try {
  const rows = await runCli('ctrip', 'package', dest);
} catch (e) {
  if (e.name === 'CommandExecutionError' && e.message.includes('package anchors')) {
    rows = await runCli('ctrip', 'package', fallbackDest); // or flag selector drift
  } else throw e;
}

Prevention

When it happens

Trigger: Running `opencli ctrip package <destination>` where the page shows package cards visually but buildVacationsExtractJs() matches no anchors — typically after a Ctrip CSS class rename (e.g. .list_product_item changed) or results rendered in a shadow DOM/iframe the extractor does not traverse.

Common situations: Ctrip front-end redesign changing card class names; A/B test variant with different markup; results delivered inside an iframe; regional Ctrip versions (overseas domains) with different DOM structure.

Related errors


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