mastra-ai/mastra · error · Error
Unknown step entry type: ${JSON.stringify(_exhaustive)}
Error message
Unknown step entry type: ${JSON.stringify(_exhaustive)} What it means
This is the exhaustive-switch default in `serializeEntry`: TypeScript's `never` check catches a `StepFlowEntry` variant the serializer doesn't recognize — usually a newly added entry type the switch wasn't updated for, or a corrupted/foreign object injected into the `stepFlow`. The thrown message embeds the JSON of the unexpected entry for diagnosis.
Source
Thrown at packages/core/src/workflows/dynamic/serialize.ts:103
}
case 'loop': {
const predicate = entry.predicate;
if (!predicate || typeof predicate !== 'object') {
throw new Error(
`Loop step "${getSingleStepEntryId(entry.step)}" cannot be stored: closure predicates do not round-trip. Use the declarative form ({ predicate: {...} }).`,
);
}
return {
type: 'loop',
step: serializeSingleEntry(entry.step),
serializedCondition: entry.serializedCondition,
loopType: entry.loopType,
predicate,
};
}
default: {
const _exhaustive: never = entry;
throw new Error(`Unknown step entry type: ${JSON.stringify(_exhaustive)}`);
}
}
}
function serializeSingleEntry(entry: SingleStepEntry): SerializedSingleStepEntry {
if (entry.type === 'agent') {
const options = pickSerializableStepOptions(entry.options, entry.id, 'agent');
const outputSchema = extractStructuredOutputJsonSchema(entry.options, entry.id);
return {
type: 'agent',
id: entry.id,
agentId: entry.agentId,
description: entry.agent?.description,
...(outputSchema ? { outputSchema } : {}),
...(options ? { options } : {}),
};
}
if (entry.type === 'tool') {View on GitHub (pinned to 75dd419e61)
Solutions
- Log/inspect the embedded JSON (`entry.type`) to identify the unknown variant.
- Update @mastra/core to a version whose serializer supports the entry type, or downgrade the producer of the graph.
- If the entry is hand-built, construct it via the library's supported entry factories instead.
- If you maintain core, extend the switch with a case for the new entry type so exhaustiveness holds.
Defensive patterns
Strategy: type-guard
Validate before calling
const KNOWN_TYPES = new Set(['step','agent','tool','mapping','sleep','sleepUntil','parallel','foreach','conditional','loop']);
for (const e of stepFlow) {
if (!e || !KNOWN_TYPES.has(e.type)) throw new Error(`Unknown step entry type: ${JSON.stringify(e)}`);
} Type guard
const isKnownEntryType = (e: unknown): e is StepFlowEntry => !!e && typeof e === 'object' && KNOWN_TYPES.has((e as any).type);
Try / catch
try {
storable = toStorableGraph(stepFlow);
} catch (e) {
if (/Unknown step entry type/.test(e.message)) {
const detail = JSON.parse(e.message.slice(e.message.indexOf(':') + 1));
// inspect detail.type; fix producer or upgrade @mastra/core
} else throw e;
} Prevention
- Construct entries only via library factories; avoid `as any` casts into StepFlowEntry.
- Keep producer and @mastra/core versions aligned for persisted graphs.
- Validate persisted graphs against the current schema before reload.
When it happens
Trigger: Calling `toStorableGraph` with a `stepFlow` array containing an entry whose `type` is not one of step/agent/tool/mapping/sleep/sleepUntil/parallel/foreach/conditional/loop — e.g. hand-assembled entries, entries from a newer core version, or data loaded from storage with an unknown type.
Common situations: Upgrading @mastra/core and feeding old persisted graphs forward; custom tooling that constructs StepFlowEntry objects manually; type assertions (`as any`) hiding a malformed entry from the compiler.
Related errors
- Unknown stored step type: ${JSON.stringify(_exhaustive)}
- SleepUntil step "${entry.id}" cannot be stored: dynamic date
- Foreach step cannot iterate a mapping: mappings project data
- Conditional (branch) step cannot be stored: closure predicat
- Loop step "${getSingleStepEntryId(entry.step)}" cannot be st
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/c7258ca1e17204a9.
Report an issue: GitHub.