jackwener/OpenCLI · error · ArgumentError

date must be YYYY-MM-DD, got "${value}"

Error message

date must be YYYY-MM-DD, got "${value}"

What it means

validateDate() requires the date string to match the YYYY-MM-DD format (DATE_RE) and rejects anything else. Thrown as ArgumentError before any network call is made, so callers get immediate feedback on malformed dates.

Source

Thrown at clis/12306/utils.js:94

    if (!trimmed) throw new ArgumentError('station must not be empty');
    if (STATION_CODE_RE.test(trimmed)) {
        const exact = stations.find((s) => s.code === trimmed);
        if (exact) return exact;
        throw new ArgumentError(`Unknown 12306 station telecode "${trimmed}"`);
    }
    const lower = trimmed.toLowerCase();
    const exactName = stations.find((s) => s.name === trimmed);
    if (exactName) return exactName;
    const exactPinyin = stations.find((s) => s.pinyin === lower);
    if (exactPinyin) return exactPinyin;
    const exactAbbr = stations.find((s) => s.abbr === lower || s.short === lower);
    if (exactAbbr) return exactAbbr;
    throw new ArgumentError(`Unknown 12306 station "${trimmed}"`, 'Try the Chinese name (上海虹桥), the 3-4 letter telecode (AOH), or full pinyin (shanghaihongqiao).');
}

export function validateDate(value) {
    if (!DATE_RE.test(String(value ?? ''))) {
        throw new ArgumentError(`date must be YYYY-MM-DD, got "${value}"`);
    }
    const [y, m, d] = value.split('-').map(Number);
    const date = new Date(Date.UTC(y, m - 1, d));
    if (date.getUTCFullYear() !== y || date.getUTCMonth() !== m - 1 || date.getUTCDate() !== d) {
        throw new ArgumentError(`date "${value}" is not a real calendar date`);
    }
    return value;
}

export function normalizeLimit(value, defaultValue, max) {
    if (value === undefined || value === null || value === '') return defaultValue;
    const n = Number(value);
    if (!Number.isInteger(n) || n < 1) {
        throw new ArgumentError(`limit must be a positive integer (1-${max})`);
    }
    if (n > max) {
        throw new ArgumentError(`limit must be <= ${max}`);
    }

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Format the value as YYYY-MM-DD before calling, e.g. date.toISOString().slice(0,10)
  2. Accept user input in local format and convert it with a date-parsing step first
  3. Validate the format in your own UI layer with the same YYYY-MM-DD regex

Example fix

// before
await query({ date: new Date() });
// after
const d = new Date();
await query({ date: d.toISOString().slice(0, 10) }); // 'YYYY-MM-DD'
Defensive patterns

Strategy: validation

Validate before calling

const DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
function isValidDateString(v) {
  const s = String(v ?? '');
  if (!DATE_RE.test(s)) return false;
  const [y, m, d] = s.split('-').map(Number);
  const dt = new Date(Date.UTC(y, m - 1, d));
  return dt.getUTCFullYear() === y && dt.getUTCMonth() === m - 1 && dt.getUTCDate() === d;
}
if (!isValidDateString(userDate)) throw new Error('date must be YYYY-MM-DD');

Type guard

function isDateString(v) {
  return typeof v === 'string' && /^\d{4}-\d{2}-\d{2}$/.test(v);
}

Try / catch

try {
  await query({ date });
} catch (e) {
  if (e instanceof ArgumentError && e.message.includes('YYYY-MM-DD')) {
    console.error('Please supply the date as YYYY-MM-DD, e.g. 2026-08-28.');
  } else throw e;
}

Prevention

When it happens

Trigger: Passing dates in other formats to date-taking commands: '2026/08/28', '28-08-2026', 'Aug 28 2026', ISO timestamps '2026-08-28T10:00:00Z', or empty/null values stringified as 'undefined'/'null'.

Common situations: Developers passing JavaScript Date objects (coerced to a different string format), reading locale-formatted dates from user input, or forgetting to format a Date before passing it.

Related errors


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