apify/crawlee · error · Error

Data item${s}is not an object. You can push only objects int

Error message

Data item${s}is not an object. You can push only objects into a dataset.

What it means

assertJsonSerializable() (used by Dataset.pushData) rejects any item that is not a non-array object. Datasets store JSON documents, so primitives, arrays, null, and undefined cannot be pushed as items.

Source

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

});

/** @internal */
export const DATASET_ITERATORS_DEFAULT_LIMIT = 10000;

/**
 * Validates that the given value is a plain JSON-serializable object
 * (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;

    /**

View on GitHub (pinned to dbe57fb09c)

Solutions

  1. Wrap primitives in an object, e.g. { value: item }.
  2. Ensure each array element passed to pushData is an object.
  3. Filter out null/undefined results before pushing.
  4. Convert non-plain objects (Dates, Maps, Sets) to plain JSON objects first.

Example fix

// before
await dataset.pushData(price); // number

// after
await dataset.pushData({ url: request.url, price });
Defensive patterns

Strategy: validation

Validate before calling

const isValidItem = (x: unknown): x is Record<string, unknown> =>
    !!x && typeof x === 'object' && !Array.isArray(x);
const items = rawResults.filter(isValidItem);
await dataset.pushData(items);

Type guard

function isDatasetItem(x: unknown): x is Record<string, unknown> {
    return typeof x === 'object' && x !== null && !Array.isArray(x);
}

Try / catch

try {
    await dataset.pushData(item);
} catch (e) {
    if (e instanceof Error && e.message.includes('not an object')) {
        await dataset.pushData({ value: item });
    } else throw e;
}

Prevention

When it happens

Trigger: pushData(42), pushData('text'), pushData([1,2,3]) (a raw array, though pushData accepts arrays of objects — a nested array element failing), pushData(null), or pushing class instances whose serialization is not a plain object.

Common situations: Scrapers accidentally pushing a raw value (e.g. response body string) instead of wrapping it, pushing null when a scrape failed, or pushing mapped arrays containing primitives.

Related errors


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