jackwener/OpenCLI · error · CommandExecutionError
Ctrip hotel-search SSR rows were missing required hotelId/na
Error message
Ctrip hotel-search SSR rows were missing required hotelId/name anchors
What it means
CommandExecutionError thrown when the extracted SSR rows all fail the filter(row => row.hotelId && row.name), i.e. after mapping, no row carries both a hotelId and a name. The list was an array (so it parsed) but its entries lack the two required anchor fields, so the library refuses to return empty-looking data.
Source
Thrown at clis/ctrip/hotel-search.js:118
if (waitResult === 'captcha') {
throw new AuthRequiredError('hotels.ctrip.com', 'Ctrip is asking for a captcha; complete it in your browser session and retry');
}
if (waitResult !== 'content') {
throw new CommandExecutionError(`Ctrip hotel-search page did not expose SSR hotel list (state=${String(waitResult)})`);
}
const raw = await page.evaluate(EXTRACT_HOTELS_JS);
if (!Array.isArray(raw)) {
throw new CommandExecutionError('Ctrip hotel-search returned malformed SSR hotel list');
}
if (raw.length === 0) {
throw new EmptyResultError('ctrip hotel-search', `No hotels for city=${cityId} on ${checkin} → ${checkout}`);
}
const rows = raw
.map((entry, i) => mapHotelRow(entry, i))
.filter((row) => row.hotelId && row.name)
.slice(0, limit);
if (rows.length === 0) {
throw new CommandExecutionError('Ctrip hotel-search SSR rows were missing required hotelId/name anchors');
}
return rows;
},
});
export const __test__ = { parseHotelLimit, assertCheckinBeforeCheckout, WAIT_FOR_SSR_JS, EXTRACT_HOTELS_JS };
View on GitHub (pinned to 49907e53dc)
Solutions
- Print one raw entry and update mapHotelRow to map the current field names to hotelId/name
- Update the CLI to a version matching current Ctrip markup
- Check whether the search params (cityId/checkin/checkout) returned only placeholder cards and use a normal city/date combo
Example fix
// before
const rows = raw.map((entry, i) => mapHotelRow(entry, i)).filter((row) => row.hotelId && row.name);
// after
const rows = raw.map((entry, i) => mapHotelRow(entry, i))
.map((row) => ({ ...row, hotelId: row.hotelId ?? row.hotelID ?? row.id, name: row.name ?? row.hotelName }))
.filter((row) => row.hotelId && row.name); Defensive patterns
Strategy: type-guard
Validate before calling
const rows = raw.map(mapHotelRow).filter((r) => r.hotelId && r.name);
if (rows.length === 0) console.warn('no rows carried hotelId/name anchors — inspect raw entries'); Type guard
const hasAnchors = (row) => typeof row === 'object' && row !== null && typeof row.hotelId === 'string' && row.hotelId.length > 0 && typeof row.name === 'string' && row.name.length > 0;
Try / catch
try {
const rows = await ctrip.hotelSearch({ cityId, checkin, checkout });
} catch (e) {
if (e instanceof CommandExecutionError && /hotelId\/name anchors/.test(e.message)) {
// treat as schema drift: alert, update mapping, or fall back to another source
} else throw e;
} Prevention
- Inspect a sample raw entry after each Ctrip release
- Keep mapHotelRow field mappings in one easy-to-update place
- Sanity-check hotel ids against a regex before use
- Monitor for sudden zero-anchor rates as a schema-drift alarm
When it happens
Trigger: EXTRACT_HOTELS_JS returns an array whose objects use different key names (e.g. hotelName/id) or whose fields are nested, so mapHotelRow cannot anchor hotelId/name on any entry; also when Ctrip serves promo/placeholder cards instead of real hotels.
Common situations: Ctrip API shape drift (renamed fields); region-specific pages with different card layouts; holiday/promotional pages with skeleton cards; a stale mapHotelRow mapping table.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Ctrip is asking for a captcha; complete it in your browser s
- Ctrip place page did not render attraction links for city id
- Ctrip attraction DOM extraction returned malformed rows
- Ctrip attraction links rendered but parser did not find requ
- Ctrip bus page did not render schedule rows (state=${String(
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/cc7c174aab50e801.
Report an issue: GitHub.