apify/crawlee · error · Error

Data item${s}is not serializable to JSON. Cause: ${err.messa

Error message

Data item${s}is not serializable to JSON.
Cause: ${err.message}

What it means

assertJsonSerializable() also probe-serializes each item with JSON.stringify; if that throws (circular references, BigInt, functions), pushData fails with this error including the underlying cause's message.

Source

Thrown at packages/core/src/storages/dataset.ts:48

 * (not an array, not a primitive, not circular).
 *
 * @param item The value to validate.
 * @param index Optional index for error messages when validating inside an array.
 * @ignore
 */
export function assertJsonSerializable<T>(item: T, index?: number): void {
    const s = typeof index === 'number' ? ` at index ${index} ` : ' ';
    const isItemObject = item && typeof item === 'object' && !Array.isArray(item);

    if (!isItemObject) {
        throw new Error(`Data item${s}is not an object. You can push only objects into a dataset.`);
    }

    try {
        JSON.stringify(item);
    } catch (e) {
        const err = e as Error;
        throw new Error(`Data item${s}is not serializable to JSON.\nCause: ${err.message}`);
    }
}

export interface DatasetDataOptions {
    /**
     * Number of array elements that should be skipped at the start.
     * @default 0
     */
    offset?: number;

    /**
     * Maximum number of array elements to return.
     * @default 250000
     */
    limit?: number;

    /**
     * If `true` then the objects are sorted by `createdAt` in descending order.

View on GitHub (pinned to dbe57fb09c)

Solutions

  1. Remove circular references before pushing (e.g. by picking only needed fields).
  2. Convert BigInt to string/number, Dates to ISO strings, Maps/Sets to arrays/objects.
  3. Use a safe replacer, e.g. JSON.parse(JSON.stringify(item, replacer)), to normalize.
  4. Push only plain objects built from explicitly selected fields.

Example fix

// before
await dataset.pushData({ user, meta: new Map([['k','v']]) });

// after
await dataset.pushData({ user, meta: Object.fromEntries(metaMap) });
Defensive patterns

Strategy: validation

Validate before calling

const safeItem = JSON.parse(JSON.stringify(item, (_k, v) => typeof v === 'bigint' ? v.toString() : v));
await dataset.pushData(safeItem);

Try / catch

try {
    await dataset.pushData(item);
} catch (e) {
    if (e instanceof Error && e.message.includes('not serializable to JSON')) {
        await dataset.pushData(JSON.parse(JSON.stringify(item, safeReplacer)));
    } else throw e;
}

Prevention

When it happens

Trigger: pushData({ a }) where a is a BigInt, a cyclic object graph, or an object containing functions/symbols that stringify throws on.

Common situations: Scraped objects retaining parent/child references (cycles), passing Playwright/Page values holding BigInts, or embedding class instances with non-serializable fields.

Related errors


AI-assisted analysis of apify/crawlee@dbe57fb09c (2026-08-30). Data as JSON: /api/errors/2dd3701b3b001f3e. Report an issue: GitHub.