{"record":{"id":"49385d78f2adb45b","repo":"can1357/oh-my-pi","slug":"invalid-date-literal-in-src","errorCode":null,"errorMessage":"invalid date literal in \"${src}\"","messagePattern":"invalid date literal in \"(.+?)\"","errorType":"exception","errorClass":"OmpTypeError","httpStatus":null,"severity":"error","filePath":"packages/omptype/src/ir.ts","lineNumber":200,"sourceCode":"const SIMPLE_OPS = \"|&()[]=?%,#\";\n\nfunction tokenize(src: string): Tok[] {\n\tconst toks: Tok[] = [];\n\tlet i = 0;\n\tconst n = src.length;\n\twhile (i < n) {\n\t\tconst c = src[i];\n\t\tif (c === \" \" || c === \"\\t\" || c === \"\\n\" || c === \"\\r\") {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (c === \"d\" && (src[i + 1] === \"'\" || src[i + 1] === '\"')) {\n\t\t\tconst quote = src[i + 1];\n\t\t\tconst end = src.indexOf(quote, i + 2);\n\t\t\tif (end < 0) throw new OmpTypeError(`unterminated date literal in \"${src}\"`);\n\t\t\tconst source = src.slice(i + 2, end).trim();\n\t\t\tconst value = /^\\d+$/.test(source) ? new Date(Number(source)) : new Date(source);\n\t\t\tif (Number.isNaN(value.valueOf())) throw new OmpTypeError(`invalid date literal in \"${src}\"`);\n\t\t\ttoks.push({ t: \"date\", v: value });\n\t\t\ti = end + 1;\n\t\t\tcontinue;\n\t\t}\n\t\tif (c === \"'\" || c === '\"') {\n\t\t\tlet j = i + 1;\n\t\t\tlet value = \"\";\n\t\t\tfor (; j < n && src[j] !== c; j++) {\n\t\t\t\tif (src[j] === \"\\\\\") {\n\t\t\t\t\tj++;\n\t\t\t\t\tif (j >= n) break;\n\t\t\t\t}\n\t\t\t\tvalue += src[j];\n\t\t\t}\n\t\t\tif (j >= n) throw new OmpTypeError(`unterminated string literal in \"${src}\"`);\n\t\t\ttoks.push({ t: \"str\", v: value });\n\t\t\ti = j + 1;\n\t\t\tcontinue;","sourceCodeStart":182,"sourceCodeEnd":218,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/omptype/src/ir.ts#L182-L218","documentation":"A date literal `d'...'` was correctly closed, but its contents do not parse to a valid `Date` (or a bare-integer epoch that yields NaN). The tokenizer validates the constructed date and throws `OmpTypeError` on `Number.isNaN(value.valueOf())`.","triggerScenarios":"`d'not-a-date'`, `d'2024-13-45'` (invalid month/day), `d''` (empty), or a numeric epoch string that produces an invalid date.","commonSituations":"Typos in dates in config/constraint strings; locale-dependent date formats (`d'31/12/2024'` parsed as month 31); empty literals from empty template variables.","solutions":["Use an ISO 8601 format the `Date` constructor accepts: `d'2024-01-01'` or `d'2024-01-01T00:00:00Z'`.","For epoch values, supply a valid numeric millisecond timestamp.","Pre-validate the date string with `!Number.isNaN(new Date(s).valueOf())` before building the expression."],"exampleFix":"// before\ntype(`date > d'31/12/2024'`); // invalid\n// after\ntype(`date > d'2024-12-31'`);","handlingStrategy":"validation","validationCode":"const d = sourceOrEpoch;\nconst value = /^\\d+$/.test(d) ? new Date(Number(d)) : new Date(d);\nif (Number.isNaN(value.valueOf())) throw new Error(`invalid date: ${d}`);","typeGuard":null,"tryCatchPattern":"try {\n  const t = new TypeExpression(src);\n} catch (err) {\n  if (err instanceof Error && err.message.includes(\"invalid date literal\")) {\n    throw new Error(`Use ISO 8601 (e.g. d'2024-01-01'): ${err.message}`);\n  }\n  throw err;\n}","preventionTips":["Use ISO 8601 date strings only (`YYYY-MM-DD` or full RFC 3339 with Z).","Avoid locale-dependent formats like DD/MM/YYYY.","Guard against empty template variables producing `d''`."],"tags":["parser","date-literal","invalid-date"],"backgroundTag":"invalid-date-literal","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}