{"record":{"id":"e4aa6eb92fa3430d","repo":"apify/crawlee","slug":"chunk-size-must-be-a-positive-number-inspect-ch","errorCode":null,"errorMessage":"Chunk size must be a positive number (${inspect(chunkSize)}) received","messagePattern":"Chunk size must be a positive number \\((.+?)\\) received","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/iterables.ts","lineNumber":47,"sourceCode":" * **Example usage:**\n * ```ts\n * const numbers = async function* () {\n *   for (let i = 1; i <= 10; i++) yield i;\n * };\n *\n * for await (const chunk of chunkedAsyncIterable(numbers(), 3)) {\n *   console.log(chunk); // [1, 2, 3], [4, 5, 6], [7, 8, 9], [10]\n * }\n * ```\n */\nexport async function* chunkedAsyncIterable<T>(\n    iterable: AsyncIterable<T> | Iterable<T>,\n    chunkSize: number | (() => number),\n): AsyncIterable<T[]> {\n    const getChunkSize = typeof chunkSize === 'function' ? chunkSize : () => chunkSize;\n\n    if (typeof chunkSize === 'number' && chunkSize < 1) {\n        throw new Error(`Chunk size must be a positive number (${inspect(chunkSize)}) received`);\n    }\n\n    const iterator =\n        Symbol.asyncIterator in iterable\n            ? (iterable as AsyncIterable<T>)[Symbol.asyncIterator]()\n            : (iterable as Iterable<T>)[Symbol.iterator]();\n\n    while (true) {\n        const currentSize = getChunkSize();\n        if (currentSize < 1) break;\n\n        const chunk: T[] = [];\n\n        for (let i = 0; i < currentSize; i++) {\n            const next = await iterator.next();\n            if (next.done) {\n                break;\n            }","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/apify/crawlee/blob/dbe57fb09ca607ad59dcf998f3925ef9ac3bb26c/packages/core/src/iterables.ts#L29-L65","documentation":"chunkedAsyncIterable groups items from an (async) iterable into arrays of a given size. When a numeric chunkSize less than 1 is passed, the library throws immediately because chunk sizes below 1 would loop forever. Function-typed chunk sizes bypass this numeric check.","triggerScenarios":"Calling chunks()/chunked()/chunkedAsyncIterable with chunkSize = 0, a negative number, or NaN from computed config values.","commonSituations":"batchSize derived from env vars that default to 0; off-by-one or float computations (e.g. Math.floor of 0.x); passing a function that returns invalid sizes (not validated here).","solutions":["Pass a chunkSize >= 1 (integer)","Clamp computed values: Math.max(1, value)","If using a function form, validate its return values yourself","Fall back to a sane default when config is missing"],"exampleFix":"// before\nconst size = Number(process.env.BATCH); iterable(chunked(items, size));\n// after\nconst size = Math.max(1, Number(process.env.BATCH) || 10); iterable(chunked(items, size));","handlingStrategy":"validation","validationCode":"const size = Number(chunkSize);\nif (!Number.isFinite(size) || size < 1) throw new Error(`chunkSize must be >= 1, got ${chunkSize}`);","typeGuard":"const isValidChunkSize = (n: unknown): n is number => typeof n === 'number' && Number.isFinite(n) && n >= 1;","tryCatchPattern":null,"preventionTips":["Clamp computed batch sizes with Math.max(1, v)","Validate env-derived numbers before use","Remember function-form chunkSize skips this check - validate its return values"],"tags":["validation","iterables","batching"],"backgroundTag":"invalid-batch-size","analyzedSha":"dbe57fb09ca607ad59dcf998f3925ef9ac3bb26c","analyzedAt":"2026-08-30T22:22:28.328Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}