mastra-ai/mastra · error · Error
Stored sleep "${entry.id}" missing literal duration.
Error message
Stored sleep "${entry.id}" missing literal duration. What it means
When rehydrating a stored workflow, a `sleep` entry must carry a literal numeric duration (durations can't be recomputed from runtime state). If entry.duration is not a number, applyGraphEntry throws this error naming the stored step id.
Source
Thrown at packages/core/src/workflows/dynamic/rehydrate.ts:100
wf: any,
entry: ValidatableStepFlowEntry,
mastra: Mastra,
schemaOpts?: JsonSchemaToZodOptions,
): void {
switch (entry.type) {
case 'agent':
case 'tool':
wf.__pushStepFlowEntry(rehydrateSingleEntry(entry, mastra, schemaOpts), entry);
return;
case 'mapping': {
const cfg = parseMapConfig(entry.mapConfig, entry.id);
const live = rehydrateMapConfig(cfg, mastra);
wf.map(live, { id: entry.id });
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;View on GitHub (pinned to 75dd419e61)
Solutions
- Fix the stored entry so duration is a literal number of milliseconds.
- Re-save the workflow step through the builder API with a numeric duration.
- Convert string/object durations to milliseconds when migrating stored definitions.
Example fix
// before
{ type: 'sleep', id: 'wait', duration: '30s' }
// after
{ type: 'sleep', id: 'wait', duration: 30000 } Defensive patterns
Strategy: validation
Validate before calling
function assertSleepEntry(entry) {
if (entry.type === 'sleep' && typeof entry.duration !== 'number') {
throw new TypeError(`Sleep step "${entry.id}" must have a numeric duration`);
}
} Type guard
function isValidSleepEntry(e: { type: string; duration?: unknown }): e is { type: 'sleep'; id: string; duration: number } {
return e.type === 'sleep' && typeof e.duration === 'number';
} Try / catch
try {
const wf = await rehydrateWorkflow(stored, mastra);
} catch (e) {
if (e instanceof Error && e.message.includes('missing literal duration')) {
// fix the stored sleep entry with a numeric duration and retry
}
throw e;
} Prevention
- Always persist sleep durations as numeric milliseconds.
- Reject non-numeric duration input in any builder UI.
- Validate stored graph entries before rehydration.
- Convert string/object durations at migration time, not runtime.
When it happens
Trigger: A stored workflow graph contains `{ type: 'sleep', id, duration: undefined/null/'30s' }` — e.g. the sleep was created from a dynamic value that was never serialized, the stored row is corrupted, or a hand-written definition used a non-numeric duration.
Common situations: Sleeps configured via a builder UI with a string like '30' or '30s' instead of a number; storage dropping the field; definitions hand-migrated from another format where duration was an object ({seconds: 30}).
Related errors
- @mastra/livekit: `workflowInput` is required when `workflow`
- Dynamic workflow bundle contains more than one definition wi
- Dynamic workflow bundle has a circular nested-workflow depen
- SCHEDULES_INVALID_WORKFLOW_PATCH
- ${path} must contain only plain objects.
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/742055035132b540.
Report an issue: GitHub.