jackwener/OpenCLI · error · CommandExecutionError
Ctrip package DOM extraction returned malformed rows
Error message
Ctrip package DOM extraction returned malformed rows
What it means
Raised by `ctrip package` when page.evaluate(buildVacationsExtractJs()) returns something other than an array. The extractor script is expected to always produce an array of raw package rows; a non-array means the in-page extraction script misbehaved or the page context corrupted its return value (e.g. non-serializable results, evaluate returning undefined on script error).
Source
Thrown at clis/ctrip/package.js:57
func: async (page, kwargs) => {
const destination = parsePlaceName('destination', kwargs.destination);
const limit = parseListLimit(kwargs.limit);
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
- Re-run once — a page-side script error can be transient
- Update the CLI to the latest version so buildVacationsExtractJs matches current Ctrip DOM
- Open the search URL in a browser devtools console and run the extract script manually to see its actual return value
- Check for page console errors during extraction (script may be clobbered by site JS)
- If you maintain the extractor, wrap collection in Array.from(...) and defensively return []
Example fix
// before
const raw = await page.evaluate(buildVacationsExtractJs());
if (!Array.isArray(raw)) throw new CommandExecutionError('...malformed rows');
// after
const raw = await page.evaluate(buildVacationsExtractJs());
const rows = Array.isArray(raw) ? raw : [];
if (rows.length === 0) throw new EmptyResultError('ctrip package', 'No packages extracted'); Defensive patterns
Strategy: try-catch
Type guard
function isRowArray(v) {
return Array.isArray(v) && v.every((r) => r && typeof r === 'object');
} Try / catch
try {
const rows = await runCli('ctrip', 'package', dest);
} catch (e) {
if (e.name === 'CommandExecutionError' && e.message.includes('malformed rows')) {
// fall back to re-run or report extractor bug
} else throw e;
} Prevention
- Keep the CLI extractor up to date with Ctrip DOM changes
- Re-run once before reporting; in-page script errors can be transient
- Avoid environments where site JS can clobber extractor globals
- Monitor for repeated occurrences — signals a structural page change
When it happens
Trigger: Running `opencli ctrip package <destination>` where the page rendered but buildVacationsExtractJs() threw inside the browser (evaluate resolves to undefined) or returned a non-array due to a script defect, instead of an array of row objects.
Common situations: Ctrip page JS overriding globals the extractor relies on; a structural change making the extractor's collection code return null; an old CLI version whose extractor no longer matches the page; Playwright/Puppeteer serialization issues with large or cyclic results.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Ctrip tour DOM extraction returned malformed rows
- Ctrip cruise DOM extraction returned malformed rows
- Ctrip round-trip flight page did not render flight cards (st
- Ctrip round-trip flight DOM extraction returned malformed ro
- Ctrip round-trip flight cards rendered but parser did not fi
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/ec9bc66cfcb7b2fd.
Report an issue: GitHub.