jackwener/OpenCLI · warning · EmptyResultError

No hotels for city ${cityId} on ${checkin} .. ${checkout}

Error message

No hotels for city ${cityId} on ${checkin} .. ${checkout}

What it means

This EmptyResultError is thrown by the trip hotel-search command after page.evaluate(buildHotelExtractJs()) successfully returns an array, but that array contains zero hotel rows. It means Trip.com responded with a well-formed but empty hotel list for the requested city and date range — the scrape pipeline worked, there was simply nothing to return.

Source

Thrown at clis/trip/hotel-search.js:65

            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,
            url: searchUrl,
        }));
    },
});

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Verify the cityId by running a Trip.com city search first to confirm it maps to a real hotel city
  2. Use dates in the near future (within Trip.com's booking window) and ensure checkout is after checkin
  3. Try a broader or nearby city id to confirm Trip.com has inventory in that region
  4. Catch EmptyResultError and treat zero rows as a valid empty result rather than a crash

Example fix

// before
const rows = await runTripHotelSearch({ cityId, checkin, checkout });
// after
try {
  const rows = await runTripHotelSearch({ cityId, checkin, checkout });
} catch (e) {
  if (e instanceof EmptyResultError) return [];
  throw e;
}
Defensive patterns

Strategy: fallback

Validate before calling

if (!cityId || !checkin || !checkout || checkin >= checkout) {
  throw new Error('hotel-search needs a valid cityId and a checkin date before checkout');
}

Try / catch

try {
  const hotels = await hotelSearch({ cityId, checkin, checkout });
} catch (e) {
  if (e.name === 'EmptyResultError') return []; // valid empty result
  throw e;
}

Prevention

When it happens

Trigger: Calling the hotel-search CLI with a cityId that has no bookable hotels on Trip.com, or with a checkin/checkout window for which the property list is empty (far-future dates, sold-out periods, or a non-hotel city id).

Common situations: Typo'd or stale cityId values, date ranges beyond Trip.com's bookable horizon, cities where Trip.com has no inventory, or dates already in the past.

Related errors


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