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
- Correct the arguments so checkout is at least one day after checkin.
- Add a pre-flight check in calling scripts: if (!(checkin < checkout)) fail early with a clear message.
- 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.
- 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
- Always pass explicit ISO date strings, never locale-dependent formats.
- Validate ci < co in wrapper scripts before invoking.
- Watch for swapped argument order when building commands programmatically.
- Remember same-day stays need checkout = checkin + 1 day minimum.
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
- --from and --to must differ (got ${fromCode})
- --depart must be before --return (got ${depart} .. ${ret})
- --from and --to must differ (got ${fromCode})
- 1688 item expects an offer URL or offer ID
- Invalid 1688 URL
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/2518d30b8cdf9ccd.
Report an issue: GitHub.