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
- Wrap primitives in an object, e.g. { value: item }.
- Ensure each array element passed to pushData is an object.
- Filter out null/undefined results before pushing.
- 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
- Always push objects; wrap primitives as { key: value }.
- Filter null/undefined and non-object entries before pushing.
- Type your scrape results as Record<string, unknown> at the source.
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
- Data item${s}is not serializable to JSON. Cause: ${err.messa
- Dataset.forEach/map/reduce() support only a "json" format.
- Failed to infer format from the path: '${path}'. Supported f
- Unsupported format: '${format}'. Use one of ${supportedForma
- Invalid "proxyUrl". Unsupported protocol: ${proxyUrl}.
AI-assisted analysis of apify/crawlee@dbe57fb09c (2026-08-30).
Data as JSON: /api/errors/75296f36b78a9928.
Report an issue: GitHub.