{"record":{"id":"8f44a22b6ff93fb6","repo":"can1357/oh-my-pi","slug":"date-bound-must-be-valid","errorCode":null,"errorMessage":"date bound must be valid","messagePattern":"date bound must be valid","errorType":"exception","errorClass":"OmpTypeError","httpStatus":null,"severity":"error","filePath":"packages/omptype/src/type.ts","lineNumber":1786,"sourceCode":"\t\t\t? { def: property.default, defFactory: typeof property.default === \"function\", hasDefault: true }\n\t\t\t: {}),\n\t};\n}\n\nfunction acceptsDateIR(ir: IR): boolean {\n\tif (ir.k === \"instance\") return ir.ctor === Date;\n\tif (ir.k === \"refine\") return acceptsDateIR(ir.base);\n\tif (ir.k === \"union\") return ir.members.every(acceptsDateIR);\n\treturn false;\n}\n\nfunction dateRefinement(\n\tschema: InternalType,\n\ttimestamp: number,\n\trelation: string,\n\tpredicate: (value: number) => boolean,\n): InternalType {\n\tif (!Number.isFinite(timestamp)) throw new OmpTypeError(\"date bound must be valid\");\n\tif (!acceptsDateIR(schema.ir)) throw new OmpTypeError(\"date bounds require a Date type\");\n\tconst bound = new Date(timestamp);\n\treturn makeType(\n\t\t{\n\t\t\tk: \"refine\",\n\t\t\tbase: schema.ir,\n\t\t\tpred: value => value instanceof Date && predicate(value.valueOf()),\n\t\t\texpected: `a Date ${relation} ${bound.toISOString()}`,\n\t\t\tjson: relation.includes(\"after\") ? { minimum: bound.toISOString() } : { maximum: bound.toISOString() },\n\t\t},\n\t\tschema[kSteps],\n\t\tmetaOf(schema),\n\t);\n}\n\nfunction selectNodes(root: IR, kind: string): readonly SelectedNode[] {\n\tconst selected: SelectedNode[] = [];\n\tconst seen = new Set<IR>();","sourceCodeStart":1768,"sourceCodeEnd":1804,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/omptype/src/type.ts#L1768-L1804","documentation":"dateRefinement() validates the timestamp bound before attaching a date refinement. A non-finite timestamp (NaN, Infinity) cannot form a valid Date bound, so omptype throws instead of producing a schema that could never match or would match everything.","triggerScenarios":"schema.minDate(Date.parse('not a date')) (NaN), schema.after(Number.POSITIVE_INFINITY), or computing a bound with a broken date parser.","commonSituations":"Parsing user-supplied date strings with Date.parse and not checking for NaN; arithmetic on dates producing NaN; timezone parse failures in config files.","solutions":["Validate the timestamp with Number.isFinite(new Date(value).getTime()) before calling the bound API","Use a strict date parser for user/config input and fail early on invalid strings","Check that a variable holding the bound is not undefined coerced through Date.parse"],"exampleFix":"// before\nconst ts = Date.parse(config.until); date.max(ts)\n// after\nconst ts = Date.parse(config.until);\nif (!Number.isFinite(ts)) throw new Error(`invalid date: ${config.until}`);\ndate.max(ts)","handlingStrategy":"validation","validationCode":"function assertValidDateBound(value) {\n  const ts = value instanceof Date ? value.getTime() : new Date(value).getTime();\n  if (!Number.isFinite(ts)) throw new Error(`invalid date bound: ${value}`);\n  return ts;\n}","typeGuard":"function isFiniteDate(d): d is Date {\n  return d instanceof Date && Number.isFinite(d.getTime());\n}","tryCatchPattern":"try {\n  return date().min(bound);\n} catch (err) {\n  if (err instanceof OmpTypeError && err.message === 'date bound must be valid') {\n    logger.error('date bound parsed to NaN/Infinity', { bound });\n    return fallbackSchema;\n  }\n  throw err;\n}","preventionTips":["Check Number.isFinite(Date.parse(s)) for every externally sourced date","Use strict date parsers for config/user input","Beware Date.parse returns NaN for ISO strings with out-of-range fields"],"tags":["omptype","date","nan","validation"],"backgroundTag":"invalid-date-bound","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}