jackwener/OpenCLI · warning · EmptyResultError
No detail exposed for hotel id ${hotelId}
Error message
No detail exposed for hotel id ${hotelId} What it means
This EmptyResultError is thrown when the SSR extraction returned a valid object but its hotelId or name fields are missing/empty — Trip.com exposed a detail payload without the core identity fields. Effectively, the site has no usable detail data for this hotel id.
Source
Thrown at clis/trip/hotel.js:50
'url',
],
func: async (page, kwargs) => {
const hotelId = parseHotelId('id', kwargs.id);
const url = buildHotelDetailUrl(hotelId);
await page.goto(url);
const waitResult = await page.evaluate(WAIT_FOR_HOTEL_DETAIL_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 detail page did not expose SSR hotel data (state=${String(waitResult)})`);
}
const detail = await page.evaluate(buildHotelDetailExtractJs());
if (!detail || typeof detail !== 'object') {
throw new CommandExecutionError('Trip.com hotel detail SSR extraction returned malformed data');
}
if (!detail.hotelId || !detail.name) {
throw new EmptyResultError('trip hotel', `No detail exposed for hotel id ${hotelId}`);
}
return [{ ...detail, url }];
},
});
View on GitHub (pinned to 49907e53dc)
Solutions
- Verify the hotel id resolves to a live Trip.com hotel page in a browser
- Refresh the hotel id from a current trip hotel-search result
- Retry with a session whose geo/locale matches the hotel's region
- Catch EmptyResultError and skip the hotel as unavailable
Example fix
// before
for (const id of ids) results.push(await tripHotelDetail({ id }));
// after
for (const id of ids) {
try { results.push(await tripHotelDetail({ id })); }
catch (e) { if (e instanceof EmptyResultError) continue; throw e; }
} Defensive patterns
Strategy: fallback
Validate before calling
const known = await hotelSearch({ cityId });
if (!known.some(h => String(h.hotelId) === String(hotelId))) {
throw new Error(`hotel ${hotelId} not in current Trip.com inventory`);
} Type guard
function hasIdentity(detail) {
return Boolean(detail) && typeof detail === 'object' &&
Boolean(detail.hotelId) && Boolean(detail.name);
} Try / catch
try {
return await tripHotelDetail({ id });
} catch (e) {
if (e instanceof EmptyResultError) return null; // skip delisted hotel
throw e;
} Prevention
- Source hotel ids from a current search, not stale bookmarks
- Skip-and-continue batch scraping when one hotel lacks detail data
- Retry region-locked ids with a matching geo/locale session
- Check the hotel page in a browser when a detail lookup repeatedly returns empty
When it happens
Trigger: detail.hotelId or detail.name is falsy after buildHotelDetailExtractJs(): invalid/unpublished hotel ids, delisted properties, or region-redirected pages that render a shell without identity data.
Common situations: Scraping a hotel id copied from an outdated listing, hotels removed from Trip.com inventory, or geo-mismatched sessions where the site serves a stub page.
Related errors
- No hotels for city ${cityId} on ${checkin} .. ${checkout}
- Trip.com hotel page did not render hotel cards (state=${Stri
- Trip.com hotel DOM extraction returned malformed rows
- Trip.com hotel detail page did not expose SSR hotel data (st
- Trip.com hotel detail SSR extraction returned malformed data
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/409ba45059955f95.
Report an issue: GitHub.