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

  1. Verify the hotel id resolves to a live Trip.com hotel page in a browser
  2. Refresh the hotel id from a current trip hotel-search result
  3. Retry with a session whose geo/locale matches the hotel's region
  4. 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

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


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/409ba45059955f95. Report an issue: GitHub.