apify/crawlee · error · Error

Dataset.forEach/map/reduce() support only a "json" format.

Error message

Dataset.forEach/map/reduce() support only a "json" format.

What it means

Dataset iteration helpers (forEach/map/reduce) only support the default 'json' format because they deserialize stored records into JavaScript objects for the iteratee callback. Requesting any other format (e.g. 'text', 'csv', 'binary') would break the typed item contract, so the library rejects it up front.

Source

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

     * **Example usage**
     * ```javascript
     * const dataset = await Dataset.open('my-results');
     * await dataset.forEach(async (item, index) => {
     *   console.log(`Item at ${index}: ${JSON.stringify(item)}`);
     * });
     * ```
     *
     * @param iteratee A function that is called for every item in the dataset.
     * @param [options] All `forEach()` parameters.
     * @param [index] Specifies the initial index number passed to the `iteratee` function.
     * @default 0
     */
    async forEach(iteratee: DatasetConsumer<Data>, options: DatasetIteratorOptions = {}, index = 0): Promise<void> {
        tryCancel();

        if (!options.offset) options.offset = 0;
        if (options.format && options.format !== 'json')
            throw new Error('Dataset.forEach/map/reduce() support only a "json" format.');
        if (!options.limit) options.limit = DATASET_ITERATORS_DEFAULT_LIMIT;

        const { items, total, limit, offset } = await this.getData(options);

        for (const item of items) {
            await iteratee(item, index++);
        }

        const newOffset = offset + limit;
        if (newOffset >= total) return;

        const newOpts = { ...options, offset: newOffset };
        await this.forEach(iteratee, newOpts, index);
    }

    /**
     * Produces a new array of values by mapping each value in list through a transformation function `iteratee()`.
     * Each invocation of `iteratee()` is called with two arguments: `(element, index)`.

View on GitHub (pinned to dbe57fb09c)

Solutions

  1. Remove the format option or set format: 'json' in the forEach/map/reduce options
  2. If you need a non-JSON representation, fetch with dataset.getData({ format: 'text' }) or export via dataset.writeToJSONFile/writeToFileToString instead
  3. Check the type of the iteratee you pass: makeText() internally calls forEach and must not receive a non-json format

Example fix

// before
await dataset.forEach(async (item) => { ... }, { format: 'text' });
// after
await dataset.forEach(async (item) => { ... }); // format defaults to 'json'
const { items } = await dataset.getData({ format: 'text' }); // if you need raw text
Defensive patterns

Strategy: validation

Validate before calling

function assertJsonFormat(options = {}) {
  if (options.format && options.format !== 'json') {
    throw new TypeError(`format '${options.format}' is not supported; use 'json'`);
  }
}
assertJsonFormat({ format: 'text' }); // throws before calling forEach

Type guard

const isJsonFormat = (f) => f === undefined || f === 'json';

Prevention

When it happens

Trigger: Calling dataset.forEach/map/reduce (directly or via dataset.map(), reduce(), addFetchedRequests() with a text consumer, or makeText()) with an options object like { format: 'text' } or any format other than 'json'.

Common situations: Developers copying export/format options from getData() or writeFileToString() into forEach/map/reduce options; older code migrated from APIs that accepted a format option; attempting to read items as raw text inside a map() call.

Related errors


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