Automattic/mongoose · error · TypeError
batchSize must be at least 1
Error message
batchSize must be at least 1
What it means
eachAsync rejects batchSize values below 1: 0 and negative numbers throw TypeError('batchSize must be at least 1'). batchSize of 0 usually means the developer intended no batching or driver default, but the server requires at least one document per batch, so Mongoose validates the lower bound eagerly.
Solutions
- Treat 0/negative as unset: const opts = n > 0 ? { batchSize: n } : {};.
- Or clamp: batchSize: Math.max(1, n).
- Fix the source producing non-positive values (env defaults, empty-length divisions).
Example fix
// before
const batchSize = Number(process.env.BATCH_SIZE ?? 0);
await cursor.eachAsync(fn, { batchSize }); // 0 -> TypeError
// after
const raw = Number(process.env.BATCH_SIZE ?? NaN);
const batchSize = Number.isInteger(raw) && raw >= 1 ? raw : undefined;
await cursor.eachAsync(fn, { batchSize }); // undefined = driver default Defensive patterns
Strategy: validation
Validate before calling
function toBatchSize(v) {
const n = v == null ? NaN : Number(v);
return Number.isInteger(n) && n >= 1 ? n : undefined; // undefined = driver default
}
await cursor.eachAsync(fn, { batchSize: toBatchSize(process.env.BATCH_SIZE) }); Type guard
function isValidBatchSize(v) {
return typeof v === 'number' && Number.isInteger(v) && v >= 1;
} Prevention
- Do not use 0 or -1 as 'use default' sentinels; use undefined/null and normalize.
- Validate env-driven numeric config at startup and clamp to minimums.
- Log the normalized batch size in ETL jobs so bad config is visible before cursors start.
When it happens
Trigger: cursor.eachAsync(fn, { batchSize: 0 }) intending unlimited; negative values from misconfigured env vars or arithmetic underflow; -1 sentinels copied from a different API's semantics.
Common situations: Env var defaulting to 0 when unset; computed batch sizes that reach 0 for empty inputs; conventions from other libraries where 0 means default.
Related errors
- batchSize must be a number
- batchSize must be an integer
- Mongoose does not support using async iterators with an…
- 2nd argument to `Model` constructor must be a POJO or…
- a circular reference in the update value, updateValue
AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21).
Data as JSON: /api/errors/96095913694bae8a.
Report an issue: GitHub.
Appendix: source
Thrown at lib/helpers/cursor/eachAsync.js:54
return new Promise((resolve, reject) => {
if (signal != null) {
if (signal.aborted) {
return resolve(null);
}
signal.addEventListener('abort', () => {
aborted = true;
return resolve(null);
}, { once: true });
}
if (batchSize != null) {
if (typeof batchSize !== 'number') {
throw new TypeError('batchSize must be a number');
} else if (!Number.isInteger(batchSize)) {
throw new TypeError('batchSize must be an integer');
} else if (batchSize < 1) {
throw new TypeError('batchSize must be at least 1');
}
}
iterate((err, res) => {
if (err != null) {
return reject(err);
}
resolve(res);
});
});
function iterate(finalCallback) {
let handleResultsInProgress = 0;
let currentDocumentIndex = 0;
let error = null;
for (let i = 0; i < parallel; ++i) {
enqueue(createFetch());View on GitHub (pinned to 49cdab0136)