mongodb/node-mongodb-native · error · MongoAPIError
Cursor returned a `null` document, but the cursor is not exh
Error message
Cursor returned a `null` document, but the cursor is not exhausted. Mapping documents to `null` is not supported in the cursor transform.
What it means
Thrown by AbstractCursor.transformDocument() when the user-supplied transform function (set via cursor.map()) returns null for a document. The driver cannot distinguish a null-transformed result from the sentinel null it uses to signal cursor exhaustion in its iteration protocol, so it refuses the mapping entirely. This is a user-API contract error, not a server problem.
Source
Thrown at src/cursor/abstract_cursor.ts:1076
// @ts-expect-error: CursorEvents is generic so Parameters<CursorEvents["close"]> may not be assignable to `[]`. Not sure how to require extenders do not add parameters.
this.emit('close');
}
} finally {
this.hasEmittedClose = true;
}
}
/** @internal */
private async transformDocument(document: NonNullable<TSchema>): Promise<NonNullable<TSchema>> {
if (this.transform == null) return document;
try {
const transformedDocument = this.transform(document);
// eslint-disable-next-line no-restricted-syntax
if (transformedDocument === null) {
const TRANSFORM_TO_NULL_ERROR =
'Cursor returned a `null` document, but the cursor is not exhausted. Mapping documents to `null` is not supported in the cursor transform.';
throw new MongoAPIError(TRANSFORM_TO_NULL_ERROR);
}
return transformedDocument;
} catch (transformError) {
try {
await this.close();
} catch (closeError) {
squashError(closeError);
}
throw transformError;
}
}
/** @internal */
protected throwIfInitialized() {
if (this.initialized) throw new MongoCursorInUseError();
}
}
View on GitHub (pinned to 3366c21a63)
Solutions
- Do not return null from map(); return a placeholder object (e.g. { __skip: true }) and filter afterwards, or return undefined and filter it out
- Use cursor.filter() / a $match stage to drop documents server-side instead of map()
- Apply the transform yourself after toArray() rather than via cursor.map()
Example fix
// before
cursor.map(doc => doc.active ? doc : null); // throws
// after (filter server-side)
const docs = await coll.find({ active: true }).toArray();
// or map to a sentinel and post-filter
cursor.map(doc => doc.active ? doc : undefined);
const docs = (await cursor.toArray()).filter(Boolean); Defensive patterns
Strategy: validation
Validate before calling
function makeTransform(fn) {
return (doc) => {
const out = fn(doc);
if (out === null) {
throw new Error('transform returned null; use filter() instead of map() for dropping docs');
}
return out;
};
}
// usage: cursor.map(makeTransform(d => d.active ? d : null)) // fails fast, clearly Type guard
const returnsNonNull = (fn) => (doc) => {
const r = fn(doc);
if (r == null) throw new Error('transform must not return null/undefined');
return r;
}; Try / catch
try {
await cursor.toArray();
} catch (e) {
if (e instanceof MongoAPIError && /Mapping documents to `null`/.test(e.message)) {
// rewrite to filter server-side
docs = await coll.find(filter).toArray();
} else throw e;
} Prevention
- Never return null from a cursor.map() transform; filter server-side instead
- Return undefined and post-filter if you must drop in the transform
- Apply transforms after toArray() when null is a legitimate value
When it happens
Trigger: Calling cursor.map(doc => conditional ? null : doc), or a transform that legitimately returns null (e.g. filtering via map, or optional fields mapped to null). Triggered on the first document for which the transform yields null during next()/toArray()/forEach()/streaming.
Common situations: Using map() to drop documents, projecting a field that can be null, or migrating a filter/map chain from another library that permits null.
Related errors
- Cursor is already initialized
- Server ended moreToCome unexpectedly
- Cursor document did not contain a batch
- Cursor must be constructed with MongoClient
- Cannot specify maxAwaitTimeMS >= timeoutMS for a tailable aw
AI-assisted analysis of mongodb/node-mongodb-native@3366c21a63 (2026-08-04).
Data as JSON: /data/errors/e2ab728239dc2e46.json.
Report an issue: GitHub.