{"record":{"id":"f9e1d60c7198b4dc","repo":"can1357/oh-my-pi","slug":"invalid-iso-datetime-value","errorCode":null,"errorMessage":"Invalid ISO datetime: ${value}","messagePattern":"Invalid ISO datetime: (.+?)","errorType":"validation","errorClass":"RangeError","httpStatus":null,"severity":"error","filePath":"packages/mnemopi/src/core/beam/helpers.ts","lineNumber":127,"sourceCode":"\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}\n}\n\nexport function parseTimestampFast(\n\tts: string | null | undefined,\n\tbeam?: Pick<BeamMemoryState, \"caches\"> | null,\n): Date | null {\n\tif (!ts) return null;","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/mnemopi/src/core/beam/helpers.ts#L109-L145","documentation":"parseIsoDateTimeUtc accepts a string intended to be ISO-8601 with UTC semantics (it normalizes a trailing Z). If `new Date(normalized)` yields an invalid time, it throws a RangeError naming the offending value. The library requires unambiguous machine-readable timestamps; it will not guess.","triggerScenarios":"Calling parseIsoDateTimeUtc (directly or via parseQueryTime/parseTimestampFast) with a string that is not valid ISO-8601, e.g. `\"2024-13-45T99:00:00Z\"`, `\"2024/01/02\"`, or an empty string.","commonSituations":"Timestamps stored with a locale-dependent format (US `MM/DD/YYYY`), human-entered dates, or truncated strings cut off mid-timestamp; also locales where Date parsing differs from expectations.","solutions":["Convert the string to strict ISO-8601, e.g. `2024-01-02T03:04:05Z`.","Use a date-only value in `YYYY-MM-DD` form, which parseQueryTime special-cases, or append `Z`/an offset yourself.","Parse with a dedicated library (e.g. Temporal or date-fns) and pass a valid Date to the API instead."],"exampleFix":"// before\nparseIsoDateTimeUtc(\"01/02/2024 3pm\");\n// after\nparseIsoDateTimeUtc(\"2024-01-02T15:00:00Z\");","handlingStrategy":"validation","validationCode":"const ISO_RE = /^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}(:\\d{2}(\\.\\d{3})?)?(Z|[+-]\\d{2}:?\\d{2})?)?$/;\nif (typeof value !== \"string\" || !ISO_RE.test(value)) throw new Error(`Not ISO-8601: ${value}`);","typeGuard":null,"tryCatchPattern":"try {\n  return parseIsoDateTimeUtc(value);\n} catch (e) {\n  if (e instanceof RangeError && e.message.startsWith(\"Invalid ISO datetime\")) {\n    return new Date(); // or rethrow with user-facing context\n  }\n  throw e;\n}","preventionTips":["Store timestamps only in strict ISO-8601 with explicit Z or offset.","Never persist locale-formatted dates (MM/DD/YYYY) in machine fields.","Round-trip test any serialization path that produces timestamp strings."],"tags":["date","iso8601","parsing","validation"],"backgroundTag":"invalid-date-value","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}