{"record":{"id":"72707c534d43ba5b","repo":"jackwener/OpenCLI","slug":"huodongxing-label-must-be-a-valid-yyyy-mm-dd-da","errorCode":null,"errorMessage":"huodongxing ${label} must be a valid YYYY-MM-DD date","messagePattern":"huodongxing (.+?) must be a valid YYYY-MM-DD date","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/huodongxing/events.js","lineNumber":65,"sourceCode":"  const year = Number(match[1]);\n  const month = Number(match[2]);\n  const day = Number(match[3]);\n  const date = new Date(Date.UTC(year, month - 1, day));\n  if (\n    date.getUTCFullYear() !== year\n    || date.getUTCMonth() !== month - 1\n    || date.getUTCDate() !== day\n  ) {\n    return null;\n  }\n  return dateOrdinal(year, month, day);\n}\n\nfunction requireYmdArg(value, label) {\n  const text = cleanText(value);\n  if (!text) return '';\n  if (parseYmd(text) == null) {\n    throw new ArgumentError(`huodongxing ${label} must be a valid YYYY-MM-DD date`);\n  }\n  return text;\n}\n\nfunction requireDateRangeArgs(args = {}) {\n  const date = requireYmdArg(args.date, 'date');\n  const dateTo = requireYmdArg(args.dateTo, 'dateTo');\n  if (date && dateTo && parseYmd(date) > parseYmd(dateTo)) {\n    throw new ArgumentError('huodongxing date must be <= dateTo');\n  }\n  return { date, dateTo };\n}\n\nfunction unwrapEvaluateResult(payload) {\n  if (payload && !Array.isArray(payload) && typeof payload === 'object' && 'session' in payload && 'data' in payload) {\n    return payload.data;\n  }\n  return payload;","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/huodongxing/events.js#L47-L83","documentation":"requireYmdArg validates optional date filters (labels 'date' and 'dateTo') for the huodongxing events command. If a non-empty value is supplied that doesn't match a strict, real YYYY-MM-DD calendar date (validated by parseYmd, including month/day range checks via Date round-trip), it throws this ArgumentError. Empty values are allowed and mean 'no filter'.","triggerScenarios":"date('2024/01/15') (slashes instead of dashes), date('15-01-2024') (wrong order), date('2024-13-01') (month 13), date('2024-02-30') (impossible day), date('tomorrow') — any non-empty value failing the ^\\d{4}-\\d{2}-\\d{2}$ pattern plus real-date check.","commonSituations":"Passing a JS Date object or ISO timestamp ('2024-01-15T10:00:00Z') instead of a date-only string; locale-formatted dates (MM/DD/YYYY); user input from forms not normalized; off-by-one month values from zero-based month math.","solutions":["Pass a real calendar date in exact YYYY-MM-DD form, e.g. date: '2024-01-15'.","Convert Date objects before calling: d.toISOString().slice(0, 10).","Pre-validate with a regex + Date round-trip at the call site and reject early with a clear message.","If the filter is optional, pass undefined/'' instead of a placeholder string like 'N/A'."],"exampleFix":"// before\nawait events({ date: new Date() });            // Date object -> ArgumentError\nawait events({ date: '2024-13-01' });          // invalid month -> ArgumentError\n// after\nawait events({ date: new Date().toISOString().slice(0, 10) }); // '2026-08-28'","handlingStrategy":"validation","validationCode":"function isValidYmd(value) {\n  const m = /^\\d{4}-\\d{2}-\\d{2}$/.exec(String(value ?? '').trim());\n  if (!m) return false;\n  const d = new Date(Date.UTC(+m[0].slice(0,4), +m[0].slice(5,7) - 1, +m[0].slice(8,10)));\n  return d.toISOString().slice(0, 10) === String(value).trim();\n}\nif (userDate && !isValidYmd(userDate)) throw new Error('date must be a valid YYYY-MM-DD date');","typeGuard":"function isYmdString(v) {\n  return typeof v === 'string' && /^\\d{4}-\\d{2}-\\d{2}$/.test(v) && isValidYmd(v);\n}","tryCatchPattern":"try {\n  await events({ date, dateTo });\n} catch (err) {\n  if (err instanceof ArgumentError && err.message.includes('YYYY-MM-DD')) {\n    console.error(`Bad date filter: ${date ?? dateTo}. Use e.g. 2026-08-28.`);\n  } else throw err;\n}","preventionTips":["Convert Date objects with toISOString().slice(0, 10) before passing.","Always zero-pad month/day (2026-08-05, not 2026-8-5).","Never pass Date objects, ISO timestamps, or locale-formatted strings directly.","Validate calendar validity (e.g. 2024-02-30 fails) with a Date round-trip, not just the regex."],"tags":["argument-validation","date-format","cli"],"backgroundTag":"invalid-date-format","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}