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

  1. Convert non-plain values before storing: JSON.parse(JSON.stringify(payload)) or explicit mapping to primitives.
  2. Convert BigInt to string and Date to ISO string explicitly.
  3. Replace class instances with plain objects ({ ...instance }) or a toDTO().
  4. 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

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


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