jackwener/OpenCLI · error · ArgumentError
${label} must be YYYY-MM-DD, got ${JSON.stringify(value)}
Error message
${label} must be YYYY-MM-DD, got ${JSON.stringify(value)} What it means
normalizeDate validates that a date parameter matches the strict YYYY-MM-DD format before building the search URL. It throws ArgumentError when the value is non-empty but does not satisfy /^\d{4}-\d{2}-\d{2}$/. This rejects formats like MM/DD/YYYY, ISO timestamps, or relative dates so downstream URL construction only ever sees canonical dates.
Source
Thrown at clis/booking/search.js:40
function normalizeNonNegativeInt(value, defaultValue, label, max) {
const raw = value ?? defaultValue;
const n = Number(raw);
if (!Number.isInteger(n) || n < 0) {
throw new ArgumentError(`${label} must be a non-negative integer`);
}
if (typeof max === 'number' && n > max) {
throw new ArgumentError(`${label} must be <= ${max}`);
}
return n;
}
function normalizeDate(value, label) {
const v = String(value || '').trim();
if (!v) {
throw new ArgumentError(`${label} is required (YYYY-MM-DD)`);
}
if (!DATE_RE.test(v)) {
throw new ArgumentError(`${label} must be YYYY-MM-DD, got ${JSON.stringify(value)}`);
}
const [year, month, day] = v.split('-').map(Number);
const d = new Date(Date.UTC(year, month - 1, day));
if (
Number.isNaN(d.getTime()) ||
d.getUTCFullYear() !== year ||
d.getUTCMonth() !== month - 1 ||
d.getUTCDate() !== day
) {
throw new ArgumentError(`${label} is not a valid calendar date: ${v}`);
}
return v;
}
function normalizeCurrency(value) {
if (value == null || value === '') return '';
const v = String(value).trim().toUpperCase();
if (!/^[A-Z]{3}$/.test(v)) {View on GitHub (pinned to 49907e53dc)
Solutions
- Reformat the value to strict YYYY-MM-DD (zero-padded month and day) before calling, e.g. with new Date(...).toISOString().slice(0, 10)
- Strip any time component: take the first 10 characters of an ISO string
- Convert Date objects via toISOString().slice(0,10) rather than template-string interpolation
- Verify the locale of the source picker and reorder DD/MM/YYYY parts into YYYY-MM-DD
Example fix
// before
const checkin = new Date();
await search(page, { checkin, checkout: '2026-09-01' });
// after
const checkin = new Date().toISOString().slice(0, 10);
await search(page, { checkin, checkout: '2026-09-01' }); Defensive patterns
Strategy: validation
Validate before calling
function isValidDateString(v) {
return typeof v === 'string' && /^\d{4}-\d{2}-\d{2}$/.test(v);
}
if (!isValidDateString(checkin) || !isValidDateString(checkout)) {
throw new Error('checkin/checkout must be YYYY-MM-DD strings');
} Type guard
function isYYYYMMDD(v) {
return typeof v === 'string' && /^\d{4}-\d{2}-\d{2}$/.test(v);
} Try / catch
try {
await search(page, { destination, checkin, checkout });
} catch (e) {
if (/must be YYYY-MM-DD/.test(e.message)) {
checkin = new Date(checkin).toISOString().slice(0, 10);
checkout = new Date(checkout).toISOString().slice(0, 10);
} else throw e;
} Prevention
- Always produce dates via toISOString().slice(0, 10), never template interpolation of Date objects
- Zero-pad month and day when building date strings manually
- Store dates in config as canonical YYYY-MM-DD strings
- Unit-test any date-generation helper against the strict format
When it happens
Trigger: Calling the search command with checkin or checkout values like '08/28/2026', '2026-8-28', '2026-08-28T00:00:00Z', 'today+7', or a JS Date object stringified to a non-ISO form; any truthy value whose String() form fails DATE_RE.
Common situations: Passing a Date object instead of a formatted string; using locale-formatted dates from a UI picker (e.g. DD/MM/YYYY); supplying unix timestamps or 'now'/'tomorrow' shortcuts; copying dates with trailing time components from API responses.
Related errors
- --expiration must use YYYY-MM-DD format
- date must be YYYY-MM-DD, got "${value}"
- date "${value}" is not a real calendar date
- archive search sort must be one of ${SORT_OPTIONS.join(', ')
- archive search mediatype must be one of ${MEDIATYPES.join(',
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/e73d604456589f04.
Report an issue: GitHub.