mastra-ai/mastra · error · Error

Stored sleepUntil "${entry.id}" has an unparseable date: ${S

Error message

Stored sleepUntil "${entry.id}" has an unparseable date: ${String(entry.date)}

What it means

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.

Source

Thrown at packages/core/src/workflows/dynamic/rehydrate.ts:114

      return;
    }
    case 'sleep': {
      if (typeof entry.duration !== 'number') {
        throw new Error(`Stored sleep "${entry.id}" missing literal duration.`);
      }
      // Push directly (not wf.sleep()) so the stored step id survives the
      // round-trip — the builder generates a fresh random id per call.
      const live: StepFlowEntry = { type: 'sleep', id: entry.id, duration: entry.duration };
      wf.__pushStepFlowEntry(live, live);
      return;
    }
    case 'sleepUntil': {
      if (!(entry.date instanceof Date) && typeof entry.date !== 'string') {
        throw new Error(`Stored sleepUntil "${entry.id}" missing literal date.`);
      }
      const date = entry.date instanceof Date ? entry.date : new Date(entry.date);
      if (Number.isNaN(date.getTime())) {
        throw new Error(`Stored sleepUntil "${entry.id}" has an unparseable date: ${String(entry.date)}`);
      }
      const live: StepFlowEntry = { type: 'sleepUntil', id: entry.id, date };
      wf.__pushStepFlowEntry(live, { type: 'sleepUntil', id: entry.id, date });
      return;
    }
    case 'parallel': {
      const live: StepFlowEntry = {
        type: 'parallel',
        steps: entry.steps.map(s => rehydrateSingleEntry(s, mastra, schemaOpts)),
      };
      wf.__pushStepFlowEntry(live, entry);
      return;
    }
    case 'foreach': {
      if (entry.step.type === 'mapping') {
        throw new Error(
          `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.`,
        );

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Fix the stored date to a valid ISO 8601 string (e.g. '2025-01-01T00:00:00.000Z').
  2. Validate the date with !Number.isNaN(new Date(v).getTime()) before persisting the workflow definition.
  3. Re-save the step through the builder/API with a corrected date.

Example fix

// before
{ type: 'sleepUntil', id: 'wait', date: '30/01/2025' }
// after
{ type: 'sleepUntil', id: 'wait', date: '2025-01-30T00:00:00.000Z' }
Defensive patterns

Strategy: validation

Validate before calling

function isParseableDate(v) {
  return (v instanceof Date || typeof v === 'string') && !Number.isNaN(new Date(v).getTime());
}
if (entry.type === 'sleepUntil' && !isParseableDate(entry.date)) {
  throw new TypeError(`sleepUntil "${entry.id}" date is not parseable: ${String(entry.date)}`);
}

Type guard

function isParseableDate(v: unknown): v is Date | string {
  return (v instanceof Date || typeof v === 'string') && !Number.isNaN(new Date(v).getTime());
}

Try / catch

try {
  const wf = await rehydrateWorkflow(stored, mastra);
} catch (e) {
  if (e instanceof Error && e.message.includes('unparseable date')) {
    // rewrite the stored date as ISO 8601 and retry
  }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: Users typing human dates in a builder UI without validation; locale-formatted date strings; timezone-less ambiguous formats in some engines; corrupted storage rows.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/8a231d3964e60ecf. Report an issue: GitHub.