jackwener/OpenCLI · warning · ArgumentError
--checkin must be earlier than --checkout (got ${checkin} >=
Error message
--checkin must be earlier than --checkout (got ${checkin} >= ${checkout}) What it means
A client-side ArgumentError from assertCheckinBeforeCheckout: the `ctrip hotel-search` command requires --checkin to be strictly earlier than --checkout. Both are parsed as ISO dates and compared at UTC midnight; if checkin >= checkout (equal dates included), the command refuses to build the hotels.ctrip.com URL, since Ctrip's list endpoint cannot serve a zero/negative-length stay.
Source
Thrown at clis/ctrip/hotel-search.js:64
const result = detect();
if (result) { observer.disconnect(); resolve(result); }
});
observer.observe(document.documentElement, { childList: true, subtree: true });
setTimeout(() => { observer.disconnect(); resolve('timeout'); }, 5000);
})
`;
const EXTRACT_HOTELS_JS = `
(() => {
const list = window.__NEXT_DATA__?.props?.pageProps?.initListData?.hotelList;
if (!Array.isArray(list)) return null;
return list;
})()
`;
function assertCheckinBeforeCheckout(checkin, checkout) {
if (Date.parse(checkin + 'T00:00:00Z') >= Date.parse(checkout + 'T00:00:00Z')) {
throw new ArgumentError(`--checkin must be earlier than --checkout (got ${checkin} >= ${checkout})`);
}
}
cli({
site: 'ctrip',
name: 'hotel-search',
access: 'read',
description: '搜索携程酒店列表(按城市 + 入住/离店日期)',
domain: 'hotels.ctrip.com',
strategy: Strategy.COOKIE,
browser: true,
navigateBefore: false,
args: [
{ name: 'city', required: true, positional: true, help: 'Numeric Ctrip city ID (use `ctrip search` or `ctrip hotel-suggest` to discover)' },
{ name: 'checkin', required: true, help: 'Check-in date (YYYY-MM-DD)' },
{ name: 'checkout', required: true, help: 'Check-out date (YYYY-MM-DD)' },
{ name: 'limit', default: DEFAULT_LIMIT, help: `Number of hotels (${MIN_LIMIT}-${MAX_LIMIT}); SSR first page returns ~13 entries` },
],View on GitHub (pinned to 49907e53dc)
Solutions
- Pass checkout strictly after checkin, e.g. --checkin 2026-09-01 --checkout 2026-09-02 for one night.
- Validate the pair in your calling code before invoking the command.
- If dates come from user input, normalize and sort them (earlier date = checkin) before calling.
Example fix
// before
await hotelSearch({ city: '1', checkin: '2026-09-05', checkout: '2026-09-01' });
// after: normalize order first
if (checkin >= checkout) [checkin, checkout] = [checkout, checkin];
await hotelSearch({ city: '1', checkin, checkout }); Defensive patterns
Strategy: validation
Validate before calling
function validateStay(checkin, checkout) {
const ci = Date.parse(checkin + 'T00:00:00Z');
const co = Date.parse(checkout + 'T00:00:00Z');
if (!(co > ci)) throw new Error(`checkout must be after checkin (got ${checkin} >= ${checkout})`);
}
validateStay(checkin, checkout); Try / catch
try {
const rows = await ctripHotelSearch({ city, checkin, checkout });
} catch (e) {
if (e instanceof ArgumentError && e.message.includes('earlier than')) {
console.error(`Bad date range: ${e.message}`); process.exitCode = 2; return [];
}
throw e;
} Prevention
- Always compare checkin < checkout in calling code before invoking.
- Auto-swap or reject equal dates; a stay needs at least one night.
- Validate dates from user input or computed date arithmetic (off-by-one bugs).
- Keep dates in ISO YYYY-MM-DD and compare with UTC-normalized parsing.
When it happens
Trigger: Calling `ctrip hotel-search <city> --checkin 2026-09-01 --checkout 2026-09-01` (same-day) or with checkout earlier than checkin (swapped order, e.g. --checkin 2026-09-05 --checkout 2026-09-01).
Common situations: Swapping the two arguments in scripts; generating a single-night stay using the same date for both fields; date arithmetic off-by-one producing checkout <= checkin; timezone-shifted strings where the author assumed a different comparison basis.
Related errors
- archive snapshots url cannot be empty
- archive snapshots limit must be a positive integer
- archive snapshots limit must be <= 1000
- archive snapshots ${key} must be a digit-only timestamp (YYY
- bilibili unfollow target must be a valid space.bilibili.com/
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/c37f527a0c89f1be.
Report an issue: GitHub.