{"record":{"id":"0b0cfecebf1c05b9","repo":"jackwener/OpenCLI","slug":"weibo-user-posts-name-must-use-yyyy-mm-dd","errorCode":null,"errorMessage":"weibo user-posts ${name} must use YYYY-MM-DD","messagePattern":"weibo user-posts (.+?) must use YYYY-MM-DD","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/weibo/user-posts.js","lineNumber":32,"sourceCode":"    if (!value) {\n        throw new ArgumentError('weibo user-posts id cannot be empty');\n    }\n    return value;\n}\n\nfunction readLimit(raw) {\n    const value = raw === undefined || raw === null || raw === '' ? DEFAULT_LIMIT : Number(raw);\n    if (!Number.isInteger(value) || value < 1 || value > MAX_LIMIT) {\n        throw new ArgumentError(`weibo user-posts limit must be an integer between 1 and ${MAX_LIMIT}`);\n    }\n    return value;\n}\n\nfunction readDate(raw, name) {\n    if (raw === undefined || raw === null || raw === '') return null;\n    const value = String(raw).trim();\n    if (!DATE_RE.test(value)) {\n        throw new ArgumentError(`weibo user-posts ${name} must use YYYY-MM-DD`);\n    }\n    const date = new Date(`${value}T00:00:00+08:00`);\n    if (!Number.isFinite(date.getTime()) || value !== formatShanghaiDate(date)) {\n        throw new ArgumentError(`weibo user-posts ${name} must be a valid calendar date`);\n    }\n    return value;\n}\n\nfunction formatShanghaiDate(date) {\n    const parts = new Intl.DateTimeFormat('en-CA', {\n        timeZone: 'Asia/Shanghai',\n        year: 'numeric',\n        month: '2-digit',\n        day: '2-digit',\n    }).formatToParts(date);\n    const get = (type) => parts.find((part) => part.type === type)?.value;\n    return `${get('year')}-${get('month')}-${get('day')}`;\n}","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/weibo/user-posts.js#L14-L50","documentation":"readDate() validates the --start/--end CLI options for the weibo user-posts command. When a date argument is present but does not match the strict YYYY-MM-DD pattern (DATE_RE), it throws this ArgumentError before any scraping happens. The library throws early so the failure is a clear input error rather than a confusing downstream empty result.","triggerScenarios":"Passing start/end values like '2024/01/15', '01-15-2024', '2024-1-5', '20240115', or a string with whitespace/extra characters to readDate via the start or end callers.","commonSituations":"Users copy dates with slashes from a file manager, scripts pass epoch timestamps, shell variable interpolation produces partial dates, or locale-formatted dates (e.g. en-US 'MM/DD/YYYY') are supplied.","solutions":["Reformat the value to strict YYYY-MM-DD with zero-padded month and day (e.g. '2024-01-15').","Check the calling script for date formatting bugs or accidental whitespace; readDate trims but the pattern still must match.","If the value may be empty/absent, pass null/undefined instead of a placeholder like '-' so readDate returns null."],"exampleFix":"// before\nnode weibo user-posts --id 123456 --start 2024/03/01 --end 2024/03/31\n// after\nnode weibo user-posts --id 123456 --start 2024-03-01 --end 2024-03-31","handlingStrategy":"validation","validationCode":"const DATE_RE = /^\\d{4}-\\d{2}-\\d{2}$/;\nfunction isValidCliDate(v) {\n  return v === undefined || v === null || v === '' || (typeof v === 'string' && DATE_RE.test(v.trim()));\n}\nif (!isValidCliDate(start) || !isValidCliDate(end)) throw new Error('dates must be YYYY-MM-DD or empty');","typeGuard":"function isDateString(v) {\n  return typeof v === 'string' && /^\\d{4}-\\d{2}-\\d{2}$/.test(v);\n}","tryCatchPattern":null,"preventionTips":["Always build date strings with an ISO formatter (e.g. toISOString().slice(0,10)) rather than manual concatenation.","Zero-pad months and days explicitly in scripts.","Pass null/undefined (not placeholders) when a bound is absent.","Unit-test any script that generates start/end values."],"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"}