Automattic/mongoose · error · MongooseError

Connection#doClose unimplemented by driver

Error message

Connection#doClose unimplemented by driver

What it means

doClose() is the abstract hook that driver adapters must implement; Connection.prototype.close() and destroy() delegate the actual socket teardown to it. The bundled node-mongodb-native driver overrides it, so a normal mongoose connection never sees this error — it appears only when a custom Connection subclass (mock, alternate driver, test double) forgot to override doClose and someone calls close() or destroy().

Source

Thrown at lib/connection.js:1320

          if (destroy && this.base.connections.indexOf(conn) !== -1) {
            this.base.connections.splice(this.base.connections.indexOf(conn), 1);
          }
          resolve();
        });
      });
  }

  return this;
};

/**
 * Abstract method that drivers must implement.
 *
 * @api private
 */

Connection.prototype.doClose = function doClose() {
  throw new MongooseError('Connection#doClose unimplemented by driver');
};

/**
 * Called when the connection closes
 *
 * @emits "close"
 * @api private
 */

Connection.prototype.onClose = function onClose(force) {
  this.readyState = STATES.disconnected;

  // avoid having the collection subscribe to our event emitter
  // to prevent 0.3 warning
  for (const i in this.collections) {
    if (Object.hasOwn(this.collections, i)) {
      this.collections[i].onClose(force);
    }

View on GitHub (pinned to 49cdab0136)

Solutions

  1. Create connections via mongoose.connect()/mongoose.createConnection() so the native driver's class is used
  2. If you maintain a custom connection class, implement doClose(force) on it
  3. In tests, stub the hook: conn.doClose = async () => {}

Example fix

// before
class FakeConnection extends Connection { /* forgot doClose */ }
await fakeConn.close(); // throws

// after
class FakeConnection extends Connection {
  async doClose(force) { /* close your transport */ return this; }
}
await fakeConn.close();
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await conn.close();
} catch (err) {
  if (/doClose unimplemented/.test(err.message)) {
    await conn.client?.close?.(); // close the underlying driver client directly
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: await conn.close() or await conn.destroy() on a connection whose class implements some driver methods but not doClose; closing a bare `new Connection()` instance.

Common situations: Writing unit-test fakes of Connection; custom driver integrations that partially implement the adapter interface; accidentally instantiating the base Connection class.

Related errors


AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21). Data as JSON: /api/errors/390d00d99dd61300. Report an issue: GitHub.