mongodb/node-mongodb-native · error · MongoRuntimeError
Cursor must be constructed with MongoClient
Error message
Cursor must be constructed with MongoClient
What it means
Thrown as a MongoRuntimeError in the AbstractCursor constructor when the first argument fails the `client.s.isMongoClient` check. Every cursor is bound to a MongoClient so it can run server selection, check out connections, track itself in `client.s.activeCursors`, and be cleaned up by MongoClient.close(). Passing anything else (a Db, Collection, plain object, or a mock) leaves the cursor without the runtime state it needs, so construction aborts. This is a programmer/internal error, not a transient runtime condition.
Solutions
- Always obtain cursors from a MongoClient-backed Collection/Db (e.g. collection.find(), db.aggregate()) instead of constructing them directly.
- If you must subclass a cursor, forward the exact MongoClient reference received from the parent cursor's `client` getter into super().
- In tests, use a real MongoClient connected to a test deployment or the driver's documented test harness rather than a hand-rolled mock that lacks `client.s.isMongoClient`.
- If you need to assert on the client type, check `client?.s?.isMongoClient === true` before constructing the cursor.
Example fix
// before (broken): passing a Db instead of the MongoClient
const cursor = new FindCursor(db, ns, options);
// after: use the Collection API, which forwards the client internally
const cursor = collection.find({}, options);
// or, when subclassing:
class MyCursor extends FindCursor {
constructor(client: MongoClient, ns: MongoDBNamespace, options: FindOptions) {
super(client, ns, options); // client must satisfy client.s.isMongoClient
}
} Defensive patterns
Strategy: validation
Validate before calling
// Verify the client is a real MongoClient before building/subclassing a cursor
function isMongoClient(v: unknown): v is MongoClient {
return !!v && typeof v === 'object' && (v as any)?.s?.isMongoClient === true;
}
if (!isMongoClient(client)) {
throw new TypeError('A MongoClient is required to construct a cursor');;
} Type guard
import type { MongoClient } from 'mongodb';
function isMongoClient(v: unknown): v is MongoClient {
return !!v && typeof v === 'object' && (v as any)?.s?.isMongoClient === true;
} Prevention
- Never construct cursors directly; always obtain them from Collection/Db methods.
- When subclassing, forward the exact MongoClient from the parent cursor's `client` getter.
- In tests, use a real MongoClient against a test deployment rather than a stub.
When it happens
Trigger: Constructing an AbstractCursor subclass (e.g. FindCursor, AggregationCursor) directly with a non-MongoClient first argument, or with an object whose `s.isMongoClient` flag is missing/false. In practice this fires when library/extension code subclasses a cursor and forgets to forward the client, or when test code passes a stub instead of a real MongoClient.
Common situations: Writing a custom cursor subclass that calls super() with a Db or Collection instead of the underlying client; mocking the driver with an object that omits the internal `s` state; migrating code that hand-constructed cursors in an older driver version.
Related errors
- Argument for maxTimeMS must be a number
- Argument "iterator" must be a function
- Cannot rewind cursor that does not own its timeout context.
- Flag is not one of
- Flag must be a boolean value
AI-assisted analysis of mongodb/node-mongodb-native@dce7939f86 (2026-08-11).
Data as JSON: /api/errors/a04ac77821734d00.
Report an issue: GitHub.
Appendix: source
Thrown at src/cursor/abstract_cursor.ts:262
/** @event */
static readonly CLOSE = 'close' as const;
/** @internal */
protected deserializationOptions: OnDemandDocumentDeserializeOptions;
protected signal: AbortSignal | undefined;
private abortListener: Disposable | undefined;
/** @internal */
protected constructor(
client: MongoClient,
namespace: MongoDBNamespace,
options: AbstractCursorOptions & Abortable = {}
) {
super();
this.on('error', noop);
if (!client.s.isMongoClient) {
throw new MongoRuntimeError('Cursor must be constructed with MongoClient');
}
this.cursorClient = client;
this.cursorNamespace = namespace;
this.cursorId = null;
this.initialized = false;
this.isClosed = false;
this.isKilled = false;
this.cursorOptions = {
readPreference:
options.readPreference && options.readPreference instanceof ReadPreference
? options.readPreference
: ReadPreference.primary,
...pluckBSONSerializeOptions(options),
timeoutMS: options?.timeoutContext?.csotEnabled()
? options.timeoutContext.timeoutMS
: options.timeoutMS,
tailable: options.tailable,
awaitData: options.awaitDataView on GitHub (pinned to dce7939f86)