jackwener/OpenCLI · error · CommandExecutionError
Trip.com hotel page did not render hotel cards (state=${Stri
Error message
Trip.com hotel page did not render hotel cards (state=${String(waitResult)}) What it means
This CommandExecutionError from clis/trip/hotel-search.js is thrown when WAIT_FOR_HOTELS_JS returns a state other than 'content' (and not 'captcha'), i.e. the hotel page loaded but hotel cards never rendered. The state string is embedded in the message (e.g. state=timeout) to identify what the waiter observed. This is a render/timing/layout problem distinct from CAPTCHA and from genuinely empty results.
Source
Thrown at clis/trip/hotel-search.js:58
'url',
],
func: async (page, kwargs) => {
const cityId = parseCityId('city', kwargs.city);
const checkin = parseIsoDate('checkin', kwargs.checkin);
const checkout = parseIsoDate('checkout', kwargs.checkout);
if (checkin >= checkout) {
throw new ArgumentError(`--checkin must be before --checkout (got ${checkin} .. ${checkout})`);
}
const limit = parseListLimit(kwargs.limit);
const searchUrl = buildHotelSearchUrl(cityId, checkin, checkout);
await page.goto(searchUrl);
const waitResult = await page.evaluate(WAIT_FOR_HOTELS_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 !== 'content') {
throw new CommandExecutionError(`Trip.com hotel page did not render hotel cards (state=${String(waitResult)})`);
}
const raw = await page.evaluate(buildHotelExtractJs());
if (!Array.isArray(raw)) {
throw new CommandExecutionError('Trip.com hotel DOM extraction returned malformed rows');
}
if (raw.length === 0) {
throw new EmptyResultError('trip hotel-search', `No hotels for city ${cityId} on ${checkin} .. ${checkout}`);
}
return raw.slice(0, limit).map((r, i) => ({
rank: i + 1,
name: r.name,
score: r.score,
reviewLabel: r.reviewLabel,
reviews: r.reviews,
location: r.location,
room: r.room,
price: r.price,
currency: r.currency,View on GitHub (pinned to 49907e53dc)
Solutions
- Check the state value in the message; for timeouts, increase the wait timeout before evaluating.
- Load the same hotel search URL in a regular browser to confirm the page still renders hotel cards.
- Update WAIT_FOR_HOTELS_JS selectors to match current Trip.com markup.
- Retry off-peak or from a different network if rendering is unreliable.
Example fix
// before
const waitResult = await page.evaluate(WAIT_FOR_HOTELS_JS);
if (waitResult !== 'content') throw new CommandExecutionError(`... (state=${waitResult})`);
// after
let waitResult = await page.evaluate(WAIT_FOR_HOTELS_JS);
if (waitResult !== 'content') {
await page.waitForSelector(HOTEL_CARD_SELECTOR, { timeout: 30000 }).catch(() => {});
waitResult = await page.evaluate(WAIT_FOR_HOTELS_JS);
}
if (waitResult !== 'content') throw new CommandExecutionError(`... (state=${waitResult})`); Defensive patterns
Strategy: retry
Validate before calling
if (!/^[a-z-]+$/i.test(String(cityId)) && !/^\d+$/.test(String(cityId))) throw new Error('invalid city id');
if (!(new Date(checkin) < new Date(checkout))) throw new Error('bad date range'); Type guard
const isRenderFailure = (e) => e instanceof CommandExecutionError && /did not render hotel cards/.test(e.message);
Try / catch
try {
await runTripHotelSearch(args);
} catch (e) {
if (isRenderFailure(e) && /state=timeout/.test(e.message)) {
await sleep(5000);
return runTripHotelSearch(args); // one bounded retry
}
throw e;
} Prevention
- Allow long timeouts for hotel pages (they are resource-heavy).
- Log state= values to distinguish timeout from layout drift.
- Keep WAIT_FOR_HOTELS_JS in sync with Trip.com markup.
- Retry timeouts once; investigate non-timeout states manually.
When it happens
Trigger: page.evaluate(WAIT_FOR_HOTELS_JS) after page.goto(searchUrl) returns 'timeout', 'error', or any unrecognized value; the extractor is never reached.
Common situations: Slow hotel-search pages (they are heavy) exceeding the waiter timeout; Trip.com changing hotel card markup so the selector never matches; headless browser resource limits stalling rendering; geo-redirects landing on an unexpected page variant.
Related errors
- Trip.com flight page did not render flight cards (state=${St
- Trip.com transfer listing did not render (state=${String(wai
- Ctrip place page did not render attraction links for city id
- Ctrip bus page did not render schedule rows (state=${String(
- Ctrip cruise page did not render (state=${String(indexWait)}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/743bf288388992f4.
Report an issue: GitHub.