jackwener/OpenCLI · error · CommandExecutionError
Ctrip bus rows rendered but parser did not find required sch
Error message
Ctrip bus rows rendered but parser did not find required schedule anchors
What it means
When the extract script returns an empty array but the scroll step counted rendered card elements (.list-item-parent), rows exist on screen but the parser failed to find its required schedule anchors in them. The CLI throws CommandExecutionError because this is a parser/DOM mismatch, not an absence of data.
Source
Thrown at clis/ctrip/bus.js:70
const limit = parseListLimit(kwargs.limit);
const searchUrl = buildBusListUrl(fromCity, toCity, date);
await page.goto(searchUrl);
const waitResult = await page.evaluate(WAIT_FOR_BUS_JS);
if (waitResult === 'captcha') {
throw new AuthRequiredError('bus.ctrip.com', 'Ctrip is asking for a captcha; complete it in your browser session and retry');
}
if (waitResult !== 'content') {
throw new CommandExecutionError(`Ctrip bus page did not render schedule rows (state=${String(waitResult)})`);
}
const renderedCardCount = await page.evaluate(buildScrollUntilJs('.list-item-parent', limit));
const raw = await page.evaluate(buildBusExtractJs());
if (!Array.isArray(raw)) {
throw new CommandExecutionError('Ctrip bus DOM extraction returned malformed rows');
}
if (raw.length === 0) {
if (Number(renderedCardCount) > 0) {
throw new CommandExecutionError('Ctrip bus rows rendered but parser did not find required schedule anchors');
}
throw new EmptyResultError('ctrip bus', `No coaches for ${fromCity} to ${toCity} on ${date}`);
}
return raw.slice(0, limit).map((r, i) => ({
rank: i + 1,
departureTime: r.departureTime,
fromStation: r.fromStation,
toStation: r.toStation,
duration: r.duration,
price: r.price,
status: r.status,
url: searchUrl,
}));
},
});
View on GitHub (pinned to 49907e53dc)
Solutions
- Rerun after a longer settle delay so row content fully hydrates before extraction
- Update buildBusExtractJs to match the current row anchor selectors
- Report/update the CLI if Ctrip changed their markup permanently
Example fix
null
Defensive patterns
Strategy: fallback
Validate before calling
null
Type guard
null
Try / catch
try {
rows = await ctripBusList({ from, to, date });
} catch (e) {
if (e instanceof CommandExecutionError && e.message.includes('schedule anchors')) {
// fallback: retry once after letting the page fully hydrate, then escalate
await sleep(5000);
try { rows = await ctripBusList({ from, to, date }); }
catch { console.error('Parser anchors stale — update buildBusExtractJs selectors'); rows = []; }
} else { throw e; }
} Prevention
- Allow extra settle time after scrolling so lazy-rendered rows hydrate before extraction
- Track ctrip markup changes affecting row anchors even when wrapper classes stay the same
- Distinguish this error (parser mismatch) from EmptyResultError (no data) in your handling code
- Add a smoke test comparing rendered card count to extracted row count
When it happens
Trigger: `clis ctrip bus` where buildScrollUntilJs('.list-item-parent', limit) reports renderedCardCount > 0 but buildBusExtractJs() returns [] because the required per-row anchor fields are missing or renamed in the DOM.
Common situations: Ctrip changing internal row markup (anchors) while keeping .list-item-parent wrappers; partially loaded rows (images/meta not hydrated); lazy-rendered cards with placeholder content at scroll time.
Related errors
- Ctrip attraction DOM extraction returned malformed rows
- Ctrip attraction links rendered but parser did not find requ
- Ctrip bus DOM extraction returned malformed rows
- Ctrip package cards rendered but parser did not find require
- Ctrip tour cards rendered but parser did not find required p
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/6dcb03424a52d732.
Report an issue: GitHub.