{"record":{"id":"8a231d3964e60ecf","repo":"mastra-ai/mastra","slug":"stored-sleepuntil-entry-id-has-an-unparseable","errorCode":null,"errorMessage":"Stored sleepUntil \"${entry.id}\" has an unparseable date: ${String(entry.date)}","messagePattern":"Stored sleepUntil \"(.+?)\" has an unparseable date: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/workflows/dynamic/rehydrate.ts","lineNumber":114,"sourceCode":"      return;\n    }\n    case 'sleep': {\n      if (typeof entry.duration !== 'number') {\n        throw new Error(`Stored sleep \"${entry.id}\" missing literal duration.`);\n      }\n      // Push directly (not wf.sleep()) so the stored step id survives the\n      // round-trip — the builder generates a fresh random id per call.\n      const live: StepFlowEntry = { type: 'sleep', id: entry.id, duration: entry.duration };\n      wf.__pushStepFlowEntry(live, live);\n      return;\n    }\n    case 'sleepUntil': {\n      if (!(entry.date instanceof Date) && typeof entry.date !== 'string') {\n        throw new Error(`Stored sleepUntil \"${entry.id}\" missing literal date.`);\n      }\n      const date = entry.date instanceof Date ? entry.date : new Date(entry.date);\n      if (Number.isNaN(date.getTime())) {\n        throw new Error(`Stored sleepUntil \"${entry.id}\" has an unparseable date: ${String(entry.date)}`);\n      }\n      const live: StepFlowEntry = { type: 'sleepUntil', id: entry.id, date };\n      wf.__pushStepFlowEntry(live, { type: 'sleepUntil', id: entry.id, date });\n      return;\n    }\n    case 'parallel': {\n      const live: StepFlowEntry = {\n        type: 'parallel',\n        steps: entry.steps.map(s => rehydrateSingleEntry(s, mastra, schemaOpts)),\n      };\n      wf.__pushStepFlowEntry(live, entry);\n      return;\n    }\n    case 'foreach': {\n      if (entry.step.type === 'mapping') {\n        throw new Error(\n          `Foreach step cannot iterate a mapping: mappings project data, they don't execute per item. Use an agent, tool, or plain step as the foreach body.`,\n        );","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/workflows/dynamic/rehydrate.ts#L96-L132","documentation":"After reading a stored sleepUntil date (string or Date), rehydrate converts it with new Date(...) and checks the result with Number.isNaN(getTime()). If the date cannot be parsed, applyGraphEntry throws this error including the stringified stored value, so the invalid value is visible in the message.","triggerScenarios":"A stored sleepUntil entry has date as a non-ISO string like 'next friday', '30/01/2025' (locale-ambiguous), an empty string, or garbage from a corrupted row — anything new Date(value) returns Invalid Date for.","commonSituations":"Users typing human dates in a builder UI without validation; locale-formatted date strings; timezone-less ambiguous formats in some engines; corrupted storage rows.","solutions":["Fix the stored date to a valid ISO 8601 string (e.g. '2025-01-01T00:00:00.000Z').","Validate the date with !Number.isNaN(new Date(v).getTime()) before persisting the workflow definition.","Re-save the step through the builder/API with a corrected date."],"exampleFix":"// before\n{ type: 'sleepUntil', id: 'wait', date: '30/01/2025' }\n// after\n{ type: 'sleepUntil', id: 'wait', date: '2025-01-30T00:00:00.000Z' }","handlingStrategy":"validation","validationCode":"function isParseableDate(v) {\n  return (v instanceof Date || typeof v === 'string') && !Number.isNaN(new Date(v).getTime());\n}\nif (entry.type === 'sleepUntil' && !isParseableDate(entry.date)) {\n  throw new TypeError(`sleepUntil \"${entry.id}\" date is not parseable: ${String(entry.date)}`);\n}","typeGuard":"function isParseableDate(v: unknown): v is Date | string {\n  return (v instanceof Date || typeof v === 'string') && !Number.isNaN(new Date(v).getTime());\n}","tryCatchPattern":"try {\n  const wf = await rehydrateWorkflow(stored, mastra);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('unparseable date')) {\n    // rewrite the stored date as ISO 8601 and retry\n  }\n  throw e;\n}","preventionTips":["Only accept ISO 8601 strings or Date objects as sleepUntil dates.","Validate with new Date(v).getTime() before persisting.","Avoid locale-dependent date formats in builder UIs.","Store dates in UTC with explicit timezone offsets."],"tags":["workflow","date","persistence"],"backgroundTag":"invalid-date-format","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}