mongodb/node-mongodb-native · error · MongoChangeStreamError

Parent provided to ChangeStream constructor must be an insta

Error message

Parent provided to ChangeStream constructor must be an instance of Collection, Db, or MongoClient

What it means

Thrown by the ChangeStream constructor when the parent argument is not an instance of Collection, Db, or MongoClient. A change stream must be rooted in one of these objects because the constructor derives the namespace, read preference, and server-selection timeout from the parent. This error usually surfaces when users try to instantiate ChangeStream directly instead of calling collection.watch()/db.watch()/client.watch().

Source

Thrown at src/change_stream.ts:663

  ) {
    super();

    this.pipeline = pipeline;
    this.options = { ...options };
    let serverSelectionTimeoutMS: number;
    delete this.options.writeConcern;

    if (parent instanceof Collection) {
      this.type = CHANGE_DOMAIN_TYPES.COLLECTION;
      serverSelectionTimeoutMS = parent.s.db.client.options.serverSelectionTimeoutMS;
    } else if (parent instanceof Db) {
      this.type = CHANGE_DOMAIN_TYPES.DATABASE;
      serverSelectionTimeoutMS = parent.client.options.serverSelectionTimeoutMS;
    } else if (parent instanceof MongoClient) {
      this.type = CHANGE_DOMAIN_TYPES.CLUSTER;
      serverSelectionTimeoutMS = parent.options.serverSelectionTimeoutMS;
    } else {
      throw new MongoChangeStreamError(
        'Parent provided to ChangeStream constructor must be an instance of Collection, Db, or MongoClient'
      );
    }

    this.contextOwner = Symbol();
    this.parent = parent;
    this.namespace = parent.s.namespace;
    if (!this.options.readPreference && parent.readPreference) {
      this.options.readPreference = parent.readPreference;
    }

    // Create contained Change Stream cursor
    this.cursor = this._createChangeStreamCursor(options);

    this.isClosed = false;
    this.mode = false;

    // Listen for any `change` listeners being added to ChangeStream

View on GitHub (pinned to 3366c21a63)

Solutions

  1. Use the public entry points: collection.watch(), db.watch(), or client.watch() instead of new ChangeStream().
  2. If mocking in tests, either instantiate a real Collection stub with the correct prototype or use a fake-timer/test double at the watch() boundary.
  3. Resolve duplicate driver installations (npm ls mongodb) so instanceof checks use the same class definition.

Example fix

// before
const stream = new ChangeStream(myPlainObject, pipeline, options);

// after
const stream = collection.watch(pipeline, options);
Defensive patterns

Strategy: type-guard

Validate before calling

import { Collection, Db, MongoClient } from 'mongodb';

function assertChangeStreamParent(parent) {
  if (!(parent instanceof Collection || parent instanceof Db || parent instanceof MongoClient)) {
    throw new TypeError('parent must be Collection, Db, or MongoClient');
  }
}

Type guard

function isChangeStreamParent(parent) {
  return parent instanceof Collection || parent instanceof Db || parent instanceof MongoClient;
}

Try / catch

try {
  stream = parent.watch(pipeline, options);
} catch (e) {
  if (e instanceof MongoChangeStreamError && /Collection, Db, or MongoClient/.test(e.message)) {
    // obtain a real Collection/Db/MongoClient before retrying
  }
}

Prevention

When it happens

Trigger: Calling new ChangeStream(someObject) directly where someObject is a plain object, a Promise, a cursor, or some other driver type (e.g. a Session or a Bulk). Passing a collection-like object from a different driver version or a mock.

Common situations: Users manually constructing a ChangeStream rather than using the watch() helper. Mocking in tests with objects that lack the proper prototype. Version skew where Collection is imported from two different driver versions (instanceof fails across module copies).

Related errors


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