Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB MongooseError: Cannot call `collection.aggregate()` before initial connection is complete

My website built with NextJS (and hosted with Vercel) is using Mongoose in my NodeJS API to connect to my MongoDB database.

I get this weird error for only about 1% of the users:

MongooseError: Cannot call `hotels.aggregate()` before initial connection is complete if `bufferCommands = false`. Make sure you `await mongoose.connect()` if you have `bufferCommands = false`.
at NativeCollection.<computed> [as aggregate] (/var/task/node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js:193:15)
at /var/task/node_modules/mongoose/lib/aggregate.js:998:18
at /var/task/node_modules/kareem/index.js:23:7
at processTicksAndRejections (internal/process/task_queues.js:77:11)

(hotels is the collection that is being displayed, and I'm calling the .aggregate() function on it in my API)

I can't reliably reproduce the error, but have had it happen to me too.

I'm following NextJS recommended way to connect to MonogoDB from their example:

import mongoose from 'mongoose'

const MONGODB_URI = process.env.MONGODB_URI

if (!MONGODB_URI) {
  throw new Error(
    'Please define the MONGODB_URI environment variable inside .env.local'
  )
}

/**
 * Global is used here to maintain a cached connection across hot reloads
 * in development. This prevents connections growing exponentially
 * during API Route usage.
 */
let cached = global.mongoose

if (!cached) {
  cached = global.mongoose = { conn: null, promise: null }
}

async function dbConnect() {
  if (cached.conn) {
    return cached.conn
  }

  if (!cached.promise) {
    const opts = {
      bufferCommands: false,
    }

    cached.promise = mongoose.connect(MONGODB_URI, opts).then((mongoose) => {
      return mongoose
    })
  }
  cached.conn = await cached.promise
  return cached.conn
}

export default dbConnect

Contrary to the error message, I am awaiting the mongoose.connect(). My API starts like this:

import dbConnect from "utils/dbConnect";
import HotelModel from "models/HotelModel";

export default async function handler(req, res) {
  await dbConnect();

      try {
        const pipeline = {}; // this is a big aggregation pipeline

        const hotels = await HotelModel.aggregate(pipeline);

        return res.status(200).json(hotels);
      } catch{
        ... 
      }
}

Does anyone have ideas to why this might happen?

like image 449
Julius Avatar asked Dec 29 '25 13:12

Julius


1 Answers

Remove

const opts = {
      bufferCommands: false,
}

or set bufferCommands: true explicitly.

Vercel is running on AWS Lambda, and sometimes it causes problems with cached connections. One of the Vercel contributors complained about the corresponding PR in mongoose https://github.com/Automattic/mongoose/issues/9239#issuecomment-659000910

They recommended to avoid bufferCommands: false in the thread and removed it from the official mongoose recommendations a year later: docs/lambda.md

like image 157
Alex Blex Avatar answered Jan 01 '26 06:01

Alex Blex



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!