jackwener/OpenCLI · error · ArgumentError

--checkin must be before --checkout (got ${checkin} .. ${che

Error message

--checkin must be before --checkout (got ${checkin} .. ${checkout})

What it means

This ArgumentError from clis/trip/hotel-search.js is thrown during argument validation when the parsed --checkin date is not strictly before --checkout (parseIsoDate output comparison checkin >= checkout). Trip.com hotel searches require a positive stay length, so the command fails before making any network request. Both dates appear in the message for easy diagnosis.

Source

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

    args: [
        { name: 'city', required: true, positional: true, help: 'Numeric Trip.com city id (discover via the hotels search box; e.g. 338 for London)' },
        { name: 'checkin', required: true, help: 'Check-in date (YYYY-MM-DD)' },
        { name: 'checkout', required: true, help: 'Check-out date (YYYY-MM-DD)' },
        { name: 'limit', type: 'int', default: 20, help: 'Number of hotels (1-50)' },
    ],
    columns: [
        'rank',
        'name', 'score', 'reviewLabel', 'reviews',
        'location', 'room',
        'price', 'currency',
        '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}`);

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Correct the arguments so checkout is at least one day after checkin.
  2. Add a pre-flight check in calling scripts: if (!(checkin < checkout)) fail early with a clear message.
  3. If same-day stays are intended, use a hotel day-use product or add one night, since this command does not support zero-night stays.
  4. Ensure date inputs are unambiguous ISO strings to avoid normalization collisions.

Example fix

// before
await runTripHotelSearch({ city: 'shanghai', checkin: '2026-09-10', checkout: '2026-09-10' });
// after
const checkin = '2026-09-10', checkout = '2026-09-11';
if (!(new Date(checkin) < new Date(checkout))) throw new Error('checkin must precede checkout');
await runTripHotelSearch({ city: 'shanghai', checkin, checkout });
Defensive patterns

Strategy: validation

Validate before calling

const ci = new Date(checkin), co = new Date(checkout);
if (isNaN(ci) || isNaN(co)) throw new Error('checkin/checkout must be ISO dates');
if (ci >= co) throw new Error(`--checkin must be before --checkout (got ${checkin} .. ${checkout})`);

Type guard

null

Try / catch

try {
  await runTripHotelSearch(args);
} catch (e) {
  if (e instanceof ArgumentError && /checkin/.test(e.message)) {
    console.error(`Fix date range: ${e.message}`);
    process.exitCode = 2;
  } else throw e;
}

Prevention

When it happens

Trigger: Invoking hotel-search with --checkin and --checkout that are equal or inverted, e.g. --checkin 2026-09-10 --checkout 2026-09-10 or --checkin 2026-09-15 --checkout 2026-09-10.

Common situations: Same-day 'day use' bookings mistakenly given identical dates; swapped arguments in a script or shell alias; timezone/time parsing making two intended-different dates normalize to the same ISO date; copy-paste errors leaving checkout as an older date.

Related errors


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