{"record":{"id":"1655aac0009ad559","repo":"mastra-ai/mastra","slug":"invalid-notification-dispatch-time-input","errorCode":null,"errorMessage":"Invalid notification dispatch time: ${input}","messagePattern":"Invalid notification dispatch time: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/notifications/workflow.ts","lineNumber":38,"sourceCode":"/**\n * The dispatcher ticks once a minute, has a single non-suspending step, and is\n * never resumed — no code path consumes its snapshot. Opting out of snapshot\n * persistence entirely keeps `mastra_workflow_snapshot` from growing by one\n * dead row per minute forever (issue #20254).\n */\nconst NOTIFICATION_DISPATCH_SHOULD_PERSIST_SNAPSHOT = () => false;\n\nexport type NotificationDispatchConfig = {\n  /** Defaults to true. Set false to opt out of automatic scheduled dispatch. */\n  enabled?: boolean;\n  cron?: string;\n  batchSize?: number;\n};\n\nexport function parseNotificationDispatchNow(input?: string): Date {\n  const now = input ? new Date(input) : new Date();\n  if (Number.isNaN(now.getTime())) {\n    throw new Error(`Invalid notification dispatch time: ${input}`);\n  }\n  return now;\n}\n\n/**\n * Builds the imperative schedule row that drives the notification dispatcher.\n * Created lazily by `Mastra.__ensureNotificationDispatchReady()` on the first\n * deferred notification, rather than declared on the workflow, so idle apps\n * never start the scheduler.\n */\nexport function buildNotificationDispatchSchedule({\n  cron = NOTIFICATION_DISPATCH_DEFAULT_CRON,\n  batchSize = NOTIFICATION_DISPATCH_DEFAULT_BATCH_SIZE,\n}: Omit<NotificationDispatchConfig, 'enabled'> = {}): Schedule {\n  const now = Date.now();\n  return {\n    id: NOTIFICATION_DISPATCH_SCHEDULE_ROW_ID,\n    target: {","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/notifications/workflow.ts#L20-L56","documentation":"parseNotificationDispatchNow converts an optional string into the dispatch 'now' Date for the notification scheduling workflow. If a string is provided but unparseable by Date, it throws rather than silently using an ambiguous date. Built-in new Date quirks (e.g. partial dates) make explicit validation worthwhile.","triggerScenarios":"Calling parseNotificationDispatchNow (or the notification workflow with a dispatch-time override) with a malformed string like 'next tuesday', '2026-13-45', or an ISO string with a bad timezone.","commonSituations":"Passing user-supplied free-text schedule times instead of ISO 8601; locale-dependent date strings; env/config values with typos (e.g. '20260829T010101Z' missing separators in some engines).","solutions":["Pass a valid ISO 8601 string (e.g. new Date().toISOString()) or omit the argument to use the current time","Validate the date string with new Date(v) and Number.isNaN(check.getTime()) before calling","Sanitize config/env inputs that feed the dispatch time","Parse user-facing dates with a dedicated parser (e.g. temporal or date-fns parse) before conversion"],"exampleFix":"// before\nparseNotificationDispatchNow('next tuesday');\n// after\nconst iso = new Date(Date.now() + 7 * 864e5).toISOString();\nparseNotificationDispatchNow(iso);","handlingStrategy":"validation","validationCode":"function toSafeDispatchNow(input?: string): Date {\n  if (!input) return new Date();\n  const d = new Date(input);\n  if (Number.isNaN(d.getTime())) throw new TypeError(`Invalid dispatch time: ${input}`);\n  return d;\n}","typeGuard":"function isValidDateString(v: unknown): v is string {\n  return typeof v === 'string' && !Number.isNaN(new Date(v).getTime());\n}","tryCatchPattern":"try {\n  const now = parseNotificationDispatchNow(rawTime);\n} catch (e) {\n  logger.error('Bad dispatch time, falling back to now', { rawTime, e });\n  const now = new Date();\n}","preventionTips":["Only pass ISO 8601 strings (Date.prototype.toISOString output)","Validate date config values at startup, not at dispatch time","Use a date library to parse user-supplied schedule text before conversion"],"tags":["notifications","date-parsing","validation"],"backgroundTag":"invalid-date-input","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}