{"record":{"id":"db8bdb34008f51fe","repo":"can1357/oh-my-pi","slug":"invalid-date","errorCode":null,"errorMessage":"Invalid Date","messagePattern":"Invalid Date","errorType":"exception","errorClass":"RangeError","httpStatus":null,"severity":"error","filePath":"packages/mnemopi/src/core/beam/helpers.ts","lineNumber":120,"sourceCode":"): HybridWeights {\n\tlet vw = Math.max(0, vecWeight ?? envNumber(\"MNEMOPI_VEC_WEIGHT\", DEFAULT_WEIGHTS[0]));\n\tlet fw = Math.max(0, ftsWeight ?? envNumber(\"MNEMOPI_FTS_WEIGHT\", DEFAULT_WEIGHTS[1]));\n\tlet iw = Math.max(0, importanceWeight ?? envNumber(\"MNEMOPI_IMPORTANCE_WEIGHT\", DEFAULT_WEIGHTS[2]));\n\tif (!Number.isFinite(vw)) vw = 0;\n\tif (!Number.isFinite(fw)) fw = 0;\n\tif (!Number.isFinite(iw)) iw = 0;\n\tconst total = vw + fw + iw;\n\tif (total === 0) return DEFAULT_WEIGHTS;\n\treturn [vw / total, fw / total, iw / total];\n}\n\nexport function normalizeImportance(importance: number | null | undefined, fallback = 0.5): number {\n\treturn clamp01(importance ?? fallback);\n}\n\nexport function normalizeDateUtc(dt: Date): Date {\n\tconst time = dt.getTime();\n\tif (!Number.isFinite(time)) throw new RangeError(\"Invalid Date\");\n\treturn new Date(time);\n}\n\nexport function parseIsoDateTimeUtc(value: string): Date {\n\tconst normalized = value.endsWith(\"Z\") ? value : value.replace(/Z$/, \"+00:00\");\n\tconst dt = new Date(normalized);\n\tif (!Number.isFinite(dt.getTime())) throw new RangeError(`Invalid ISO datetime: ${value}`);\n\treturn dt;\n}\n\nexport function parseQueryTime(queryTime?: string | Date | null): Date {\n\tif (queryTime == null) return new Date();\n\tif (queryTime instanceof Date) return normalizeDateUtc(queryTime);\n\ttry {\n\t\treturn parseIsoDateTimeUtc(queryTime);\n\t} catch {\n\t\treturn parseIsoDateTimeUtc(`${queryTime}T00:00:00`);\n\t}","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/mnemopi/src/core/beam/helpers.ts#L102-L138","documentation":"normalizeDateUtc validates that a Date object holds a real, finite timestamp before re-wrapping it. JavaScript allows constructing Dates that hold NaN (e.g. `new Date(\"garbage\")` or `new Date(NaN)`), and this library refuses to propagate such values into scoring/recall math, throwing a RangeError instead of silently producing NaN scores.","triggerScenarios":"Calling an API that accepts `queryTime` (via parseQueryTime) with a Date instance created from an unparseable string, NaN, or an out-of-range numeric value, so `dt.getTime()` returns NaN and `Number.isFinite` fails.","commonSituations":"Passing a Date parsed from user-supplied free-text input, deserializing a JSON value like `\"undefined\"` into a Date, or doing date arithmetic that overflows (e.g. adding Infinity hours).","solutions":["Validate the Date before passing it: check `Number.isFinite(date.getTime())`.","If constructing from a string, use parseIsoDateTimeUtc or parseQueryTime with a proper ISO-8601 string (optionally with Z or offset).","If the Date came from user input, surface a validation message instead of constructing an invalid Date."],"exampleFix":"// before\nconst queryTime = new Date(userInput); // userInput = \"next tuesday-ish\"\nrecall(query, { queryTime });\n// after\nconst queryTime = new Date(userInput);\nif (Number.isNaN(queryTime.getTime())) throw new Error(`Unparseable date: ${userInput}`);\nrecall(query, { queryTime });","handlingStrategy":"validation","validationCode":"function isValidDate(d: unknown): d is Date {\n  return d instanceof Date && Number.isFinite(d.getTime());\n}\n// before calling: if (!isValidDate(queryTime)) throw new Error(\"bad queryTime\");","typeGuard":"function isValidDate(d: unknown): d is Date {\n  return d instanceof Date && Number.isFinite(d.getTime());\n}","tryCatchPattern":"try {\n  const qt = normalizeDateUtc(candidate);\n} catch (e) {\n  if (e instanceof RangeError && e.message === \"Invalid Date\") {\n    // fall back to new Date()\n  } else throw e;\n}","preventionTips":["Never construct Dates from unvalidated user text; parse and check getTime() first.","Guard date arithmetic results with Number.isFinite before use.","Prefer ISO strings at API boundaries and convert to Date only after validation."],"tags":["date","validation","rangeerror","nan"],"backgroundTag":"invalid-date-value","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}