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
- Remove the format option or set format: 'json' in the forEach/map/reduce options
- If you need a non-JSON representation, fetch with dataset.getData({ format: 'text' }) or export via dataset.writeToJSONFile/writeToFileToString instead
- 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
- Omit the format option entirely for forEach/map/reduce
- Use getData()/writeToFile() for non-JSON formats
- Keep iterator options limited to offset/limit
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
- Data item${s}is not an object. You can push only objects int
- Request options are not valid, the 'id' property must not be
- At most one of `body`, `form` and `json` may be specified in
- Failed to infer format from the path: '${path}'. Supported f
- Unsupported format: '${format}'. Use one of ${supportedForma
AI-assisted analysis of apify/crawlee@dbe57fb09c (2026-08-30).
Data as JSON: /api/errors/6def6acd16baecf5.
Report an issue: GitHub.