mongodb/node-mongodb-native · critical · MongoRuntimeError

Cursor must be constructed with MongoClient

Error message

Cursor must be constructed with MongoClient

What it means

Thrown by the AbstractCursor constructor when the supplied client is not a genuine MongoClient instance (the internal isMongoClient flag is false). Cursors must be backed by a real client because they depend on its session pool, topology, and SDAM state.

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.awaitData

View on GitHub (pinned to 3366c21a63)

Solutions

  1. Obtain the client via MongoClient.connect() or new MongoClient(uri).connect() and pass that exact instance.
  2. In tests, mock at the operation/server layer rather than fabricating a cursor directly.
  3. If you have a Db/Collection, use collection.find() which internally forwards the correct client.

Example fix

// before
cursor = new FindCursor(collection, ns, {}); // wrong first arg
// after
cursor = collection.find({}); // let the driver build the cursor
Defensive patterns

Strategy: type-guard

Validate before calling

import { MongoClient } from 'mongodb';
function isRealClient(v) { return v instanceof MongoClient; }

Type guard

function isMongoClient(v): v is MongoClient { return v instanceof MongoClient && !!v?.s?.isMongoClient; }

Prevention

When it happens

Trigger: Constructing a cursor with a plain object, a mock, a Db/Collection instance mistaken for a client, a client from an incompatible driver version, or a client whose symbol was stripped (e.g. by serialization/structuredClone).

Common situations: Test code passing a stub client; refactoring that passes `collection` or `db` where `client` was expected; using two installed copies of the driver where instanceof checks fail across module instances.

Related errors


AI-assisted analysis of mongodb/node-mongodb-native@3366c21a63 (2026-08-04). Data as JSON: /data/errors/a04ac77821734d00.json. Report an issue: GitHub.