jackwener/OpenCLI · error · ArgumentError

checkout (${checkout}) must be after checkin (${checkin})

Error message

checkout (${checkout}) must be after checkin (${checkin})

What it means

This ArgumentError is thrown by the booking search command when the checkout date is not strictly after the checkin date. The library normalizes both dates to a comparable form and performs a simple string/lexicographic comparison (checkin >= checkout), so equal or inverted ranges are rejected before any browser automation starts. It exists to prevent building a Booking.com URL with an invalid date range that would yield no results or an error page.

Source

Thrown at clis/booking/search.js:245

    'name',
    'country',
    'slug',
    'star_rating',
    'review_score',
    'review_count',
    'price_amount',
    'price_currency',
    'distance',
    'recommended_room',
    'url',
  ],
  func: async (page, kwargs) => {
    const destination = String(kwargs.destination || '').trim();
    if (!destination) throw new ArgumentError('destination is required');
    const checkin = normalizeDate(kwargs.checkin, 'checkin');
    const checkout = normalizeDate(kwargs.checkout, 'checkout');
    if (checkin >= checkout) {
      throw new ArgumentError(`checkout (${checkout}) must be after checkin (${checkin})`);
    }
    const adults = normalizePositiveInt(kwargs.adults, 2, 'adults', 30);
    const rooms = normalizePositiveInt(kwargs.rooms, 1, 'rooms', 30);
    const children = normalizeNonNegativeInt(kwargs.children, 0, 'children', 10);
    const currency = normalizeCurrency(kwargs.currency);
    const lang = normalizeLang(kwargs.lang);
    const limit = normalizePositiveInt(kwargs.limit, 25, 'limit', 100);
    const offset = normalizeNonNegativeInt(kwargs.offset, 0, 'offset', 1000);

    const url = buildSearchUrl({ destination, checkin, checkout, adults, rooms, children, offset, currency, lang });

    try {
      await page.goto(url);
    } catch (err) {
      throw new CommandExecutionError(`Failed to load Booking.com search page: ${err?.message || err}`);
    }

    // Booking lazy-loads price cells; wait for at least the first card price to settle.

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Pass a checkout date strictly after checkin (at least one night apart).
  2. Swap the values if they were accidentally reversed.
  3. Verify date format expected by normalizeDate (ISO yyyy-mm-dd) and convert before calling.
  4. If a same-day booking is intended, this API does not support it; check for a dedicated option or use a different tool.

Example fix

// before
await run('booking.search', { destination: 'Paris', checkin: '2026-05-10', checkout: '2026-05-10' });
// after
await run('booking.search', { destination: 'Paris', checkin: '2026-05-10', checkout: '2026-05-11' });
Defensive patterns

Strategy: validation

Validate before calling

function assertValidStay(checkin, checkout) {
  const ckin = new Date(checkin), ckout = new Date(checkout);
  if (isNaN(ckin) || isNaN(ckout)) throw new Error('dates must be valid');
  if (ckout <= ckin) throw new Error(`checkout (${checkout}) must be after checkin (${checkin})`);
}
// call before the API:
assertValidStay('2026-05-10', '2026-05-11');

Type guard

const isAfter = (checkin, checkout) => String(checkout) > String(checkin); // ISO dates compare lexicographically

Try / catch

try {
  await booking.search({ destination, checkin, checkout });
} catch (e) {
  if (e instanceof ArgumentError && /must be after checkin/.test(e.message)) {
    [checkin, checkout] = [checkin, addDays(checkin, 1)]; // or surface to user
  } else throw e;
}

Prevention

When it happens

Trigger: Calling the search command with checkin equal to checkout (e.g. checkin=2026-01-10, checkout=2026-01-10), or with checkout earlier than checkin (e.g. dates swapped or checkout omitted and defaulted to a date before checkin).

Common situations: Users passing a single-night stay as the same date for both fields; computing dates with an off-by-one or swapped variable; passing MM/DD vs DD/MM formats so normalizeDate parses them differently than expected; passing checkout as a relative date like 'tomorrow' when checkin was 'today+2'.

Related errors


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