mastra-ai/mastra · error · MastraError
DATASET_ITEM_PAYLOAD_NOT_SERIALIZABLE
DATASET_ITEM_PAYLOAD_NOT_SERIALIZABLE
Error message
Dataset item payload must be JSON-serializable: ${issue.reason}. What it means
Pre-write validation that a dataset item's payload can round-trip through JSON. When a field contains a non-serializable value (function, BigInt, class instance, circular reference), a MastraError with code DATASET_ITEM_PAYLOAD_NOT_SERIALIZABLE is thrown, carrying the offending path and a reference path for class instances.
Source
Thrown at packages/core/src/storage/domains/datasets/serialization.ts:86
return undefined;
}
type SerializableDatasetItemPayload = Partial<Omit<DatasetItemPayload, 'scorerIds'>> &
Pick<UpdateDatasetItemInput, 'scorerIds'>;
export function validateDatasetItemPayloadSerialization(payload: SerializableDatasetItemPayload, path: string): void {
const ancestors = new WeakMap<object, string>();
ancestors.set(payload, path);
for (const key of Object.keys(payload)) {
const fieldValue = (payload as Record<string, unknown>)[key];
// Omitted optional fields: only nested undefined values are lossy.
if (fieldValue === undefined) continue;
const issue = findSerializationIssue(fieldValue, formatPath(path, key), ancestors);
if (issue) {
throw new MastraError({
id: 'DATASET_ITEM_PAYLOAD_NOT_SERIALIZABLE',
text: `Dataset item payload must be JSON-serializable: ${issue.reason}.`,
domain: 'STORAGE',
category: 'USER',
details: issue.referencePath
? { path: issue.path, referencePath: issue.referencePath }
: { path: issue.path, reason: issue.reason },
});
}
}
try {
JSON.stringify(payload);
} catch (error) {
throw new MastraError({
id: 'DATASET_ITEM_PAYLOAD_NOT_SERIALIZABLE',
text: `Dataset item payload at ${path} must be JSON-serializable: ${error instanceof Error ? error.message : String(error)}`,
domain: 'STORAGE',View on GitHub (pinned to 75dd419e61)
Solutions
- Convert non-plain values before storing: JSON.parse(JSON.stringify(payload)) or explicit mapping to primitives.
- Convert BigInt to string and Date to ISO string explicitly.
- Replace class instances with plain objects ({ ...instance }) or a toDTO().
- Remove circular references or replace with ids/refs.
Example fix
// before
await storage.datasets.updateItem({ datasetId, id, payload: { createdAt: new Date(), meta: bigIntCount } });
// after
await storage.datasets.updateItem({ datasetId, id, payload: { createdAt: new Date().toISOString(), meta: String(bigIntCount) } }); Defensive patterns
Strategy: validation
Validate before calling
function isJsonSerializable(value: unknown, seen = new WeakSet<object>()): boolean {
if (value === null || ['string', 'number', 'boolean'].includes(typeof value)) return true;
if (typeof value === 'bigint' || typeof value === 'function' || typeof value === 'symbol') return false;
if (typeof value !== 'object') return false;
if (seen.has(value)) return false;
seen.add(value);
return Object.values(value as Record<string, unknown>).every(v => isJsonSerializable(v, seen));
}
// before writing: if (!isJsonSerializable(payload)) sanitize(payload); Type guard
function isPlainPayload(p: unknown): p is Record<string, string | number | boolean | null | Array<unknown> | object> {
return isJsonSerializable(p);
} Try / catch
try {
await storage.datasets.updateItem({ datasetId, id, payload });
} catch (e) {
if ((e as any).id === 'DATASET_ITEM_PAYLOAD_NOT_SERIALIZABLE') {
const { path, referencePath } = (e as any).details ?? {};
// fix payload at `path` (convert class instance at referencePath to plain object)
} else throw e;
} Prevention
- Map payloads to plain JSON types (string/number/boolean/null/array/plain object) at construction.
- Convert Date -> ISO string and BigInt -> string explicitly.
- Strip functions and class instances before persisting.
- Reuse one sanitize-payload helper in all write paths.
When it happens
Trigger: updateItem or batchInsertItems with a payload containing a function, Symbol, BigInt, Date-like class instance, Map/Set, or a circular structure; computed object values returning class instances instead of plain objects.
Common situations: Passing AI/tool call results containing class instances directly as item payloads; embedding a callback in the payload by accident; building payloads from DB rows that include Buffer/BigInt columns.
Related errors
- DATASETS_STORAGE_NOT_CONFIGURED
- DATASETS_STORE_NOT_AVAILABLE
- DATASET_NOT_FOUND
- EXPERIMENT_HAS_NO_TARGET
- EXPERIMENT_ALREADY_FINALIZED
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/b99c66033d0f01cf.
Report an issue: GitHub.