Mongoose: DeprecationWarning: Mongoose: mpromise (mongoose's default promise library) is deprecated with 4.8.0 and 4.8.1

Created on 2 Feb 2017  ·  37Comments  ·  Source: Automattic/mongoose

With mongoose versions 4.8.0 and 4.8.1 (node version is 6.9.5 and MongoDB version is 3.2.11) the following warning is generated the first time the save of a document occurs after starting the application (the warning does not appear when the same code is executed subsequent times after the first time while the application is still running, however, if the application is closed and restarted, then the first time a document save occurs after the application has been started the warning is generated):

DeprecationWarning: Mongoose: mpromise (mongoose's default promise library) is deprecated, plug in your own promise library instead: http://mongoosejs.com/docs/promises.html

This issue does not appear when using the exact same application code with mongoose versions 4.7.9 and earlier.

The code that sets up the mongoose connection is as follows:

`// Set up mongoose and DB connection
 var mongoose = require('mongoose');
 mongoose.Promise = require('bluebird');
 mongoose.connect('mongodb://localhost:27017/basedir', {server: { poolSize: 5 }});`
help wanted needs clarification

Most helpful comment

Howto Fix Deprecation Warning:

var mongoose = require('mongoose');

mongoose.Promise = global.Promise;
var schema = new mongoose.Schema({
 // definition
}, {
 // options
});

module.exports = mongoose.model('foobar', schema);

All 37 comments

Can you paste the code that actually produces the error? That code won't because you haven't used a promise yet (unless you're saying that the connection snippet you posted does produce the warning?)

No the connection snippet does not produce the warning. The following newuser save snippet is the code that produces the warning, but only the first time that the code is executed after the application has been started (again, the warning does not occur in mongoose versions 4.7.9 and earlier):

 `                       var curDate = new Date();

                         var newuser = new user(
                         {                             
                                "userName": userName,
                                "hashed_password": hashed_password,
                                "emailReg": false,
                                "email": "~",
                                "firstName": "",
                                "lastName": "",
                                "address.streetAddress": "",
                                "address.city": "",
                                "address.state": "",
                                "address.postalCode": "",
                                "phoneNumbers": [],
                                "accessLevel": 2,
                                "active": true,
                                "trialStartDate": curDate,
                                "maxStorageByteLimit": constants.maxStorageBytesPerUser,
                                "signUpDate": curDate,
                                "passwordResetDate": curDate,
                                "salt": temp,
                                "storageBytesUsed": 0
                            });

                        if (phoneNumberValid != false)
                        {
                            newuser.phoneNumbers.push({
                                "type": "mobile",
                                "number": contactPhoneNumber,
                                "primary": true
                            });
                        }

                        wlogger.crit("Create new user by UserName: " + userName);

                        newuser.save(function (err)
                        {
                            if (err)
                            {
                                wlogger.error(err + " - when saving user "
                                    + " creation by UserName: " + userName);
                                callback({
                                    "response": false,
                                    "res": "User creation failed. "
                                    + " Please try again or contact us at [email protected]"
                                });
                            }
                            else
                            {
                                wlogger.crit("Saved new user info for UserName: "
                                    + userName);

                                return callback({
                                        "response": true,
                                        "res": "Created user by User Name " + userName,
                                        "user_id": newuser._id,
                                        "last_modified_date": curDate
                                });
                            }
                        })`

The user schema is as follows:

`var userSchema = mongoose.Schema({ 
token : String,
email: String,
userName: String,
deviceId: String,
devicePhoneNumber: String, 
hashed_password: String, 
hashed_admin_code: String,
maxStorageByteLimit: { type: Number, default: 1073741824 },
accessLevel: { type: Number, default: 2 },
lastAccessType: Number,
storageBytesUsed: { type: Number, default: 0 },
totalStorageBytesUsed: { type: Number, default: 0 },
deletedStorageBytesUsed: { type: Number, default: 0 },
salt : String,
salt1 : String,
temp_str: String,
syncInProcess: { type: Boolean, default: false },
syncStartDate: { type: Date, default: Date.now },
syncVersion : { type: Number, default: 0 },
active: { type: Boolean, default: false },
disabled: { type: Boolean, default: false },
emailReg: { type: Boolean, default: false },
regPending: { type: Boolean, default: false },
emailChangePending: { type: Boolean, default: false },
regCodeSendCount: { type: Number, default: 0 },
trialStartDate: Date,
signUpDate: Date,
passwordResetDate: Date,
lastLoginDate: Date,
lastModifiedDate: Date,
curLoginDate: Date,
apnDeviceTokens: [ String ],
curSessionIds: [ String ],
curIpAddr: { ipType: String, 
    upper64: Schema.Types.Long,
    lower64: Schema.Types.Long },
firstName: String,
lastName: String,
address: { streetAddress: String,
    city: String,
    state: String, postalCode: String },
phoneNumbers: [ phoneNumbersSchema ],
categories: [ categoriesSchema ],
providerCustomers: [ customerSchema ],
serviceProviders: [ providerSchema ],
ipAddrs: [ ipAddrSchema ],
recentUploads: [ recentUploadSchema ],
recentUploadsGizmo: [ recentUploadSchema ],
recentUploadsLife: [ recentUploadSchema ],
recentUploadsVehicle: [ recentUploadSchema ],
recentUploadsMisc: [ recentUploadSchema ],
recentViews: [ recentViewsSchema ],
recentAdds: [ recentAddsSchema ],
recentAddedFiles: [ recentAddedFilesSchema ],
locations: [ locationSchema ],
inMessages: [ inMessageSchema],
outMessages: [ outMessageSchema ]
  });`

I can confirm the same problem with mongoose v4.8.1 & node.js v7.5.0.

mongoose.Promise = global.Promise;
mongoose.connect(db.mongodb.uri, db.mongodb.options);
DeprecationWarning: Mongoose: mpromise (mongoose's default promise library) is deprecated, plug in your own promise library instead: http://mongoosejs.com/docs/promises.html

@stevenelson74708 thanks for the snippet, but the schema itself probably isn't the problem. What i'm looking for more is how the schema gets imported and used relative to when the connection is opened / the mongoose Promise constructor is set.

The schema is exported from the schema file where it is declared as follows:

`module.exports = mongoose.model('users', userSchema);   `

and the schema is imported into the file it is used where newuser.save is called as follows:

`var user = require('config/models/users');`

The connect snippet (where the connection is open and the mongoose Promise constructor is set) shown in my first post occurs in the app.js file which runs at initialization during application startup.

The newuser.save snippet shown in my second post gets executed from the file where the user schema is imported and the newuser.save gets executed when a user interacts with the application and causes a specific route to be executed, which is well after application initialization has been completed.

The warning occurs only the first time the newuser.save code executes after application startup even though the same newuser.save code is executed many times after startup, and the warning does not appear to occur with mongoose versions 4.7.9 and earlier.

@stevenelson74708 i'm going to need to see all of the components that play a role in your app's startup. A lot of people have opened issues recently regarding this, and every single one has stemmed from improperly setting the promise constructor, so my guess is you're doing something wrong in the order in which you set mongoose.Promise.

Is there any way that I can see your code?

Below is all the code (in exact order) in the app.js initialization that is related to mongoose configuration, including setting mongoose.Promise. The warning does not occur when the initialization code executes. The warning only occurs the first time the newuser.save code (show in my previous post) executes after the application has been initialized. There are findOneAndUpdate calls that execute before the save that don't cause the warning, so it appears that it's only the save functionality that causes the warning.

The mongoose configuration is one of the first things that occurs in the initialization. Should the mongoose configuration occur later in the initialization such as after the createServer functionality?

Again, the warning does not appear to occur in mongoose versions 4.7.9 and earlier:

`// Set up mongoose and DB connection
var mongoose = require('mongoose');

mongoose.Promise = require('bluebird');
mongoose.connect('mongodb://localhost:27017/basedir', {server: { poolSize: 5 }});
var conn = mongoose.connection;

conn.once('open', function ()
{
    wlogger.info("Mongoose connection opened on process " + process.pid);
});`

No, the configuration can come first. Is this file the entry point for your app or is there a file that precedes this?

The app.js file is the entry point for the application. The application can be invoked by typing node app.js at the command line.

I have same problem with mongoose 4.8.1 and node 7.5.0. I am also using Typescript and trying to plug Bluebird for promises. I found out that warning disappears if i add this code:

`import * as mongoose from 'mongoose';
 import * as bluebird from 'bluebird';

 (<any>mongoose).Promise = bluebird;`

in EVERY file that imports something from 'mongoose'. So i need to do that in every model file (file where i define my schema) instead in entry point file only.

// Set up mongoose and DB connection
var mongoose = require('mongoose');

mongoose.Promise = require('bluebird');
mongoose.connect('mongodb://localhost:27017/basedir', {server: { poolSize: 5 }});
var conn = mongoose.connection;

conn.once('open', function ()
{
    console.log('test');
});

Doesn't print this warning, so there's something else.

@vladimirdjurdjevic this means that somewhere you're using a mongoose async op before setting the promise lib. I don't use TS so I don't know if that has anything to do with it.

I set the promise lib as shown above in the app.js file which is the entry point of the application, and then when the first newuser.save is performed (long after the promise lib has been set) as shown above the warning occurs. The newuser.save is the first mongoose async op that occurs, but it occurs well after the promise is lib is set for the connection.

Does the promise lib have to be set in each file that accesses mongoose async functions as opposed to setting the promise lib only once when the mongoose connection is configured?

@stevenelson74708 I had the same problem. I thought I resolved it with: mongoose.Promise = global.Promise in the entry point of the application. Looks like you do need it in every file that accesses mongoose promises. Pretty annoying. Just set the mongoose configuration in a separate file, export it and import it wherever needed.

I also recently noticed that I'm getting this warning, although I've set the promise in my app.js file. I've tried using both native and bluebird with the same results.

// FILE: app.js
import bluebird from 'bluebird';
import mongoose from 'mongoose';

// use bluebird as default promise library
mongoose.Promise = bluebird;

I'm importing mongoose into a few of my models and using them in schema methods. I've solved the problem by setting the promise library in ever file that imports mongoose on its own (see the TODO in the snippet below). I don't recall seeing the warning a few months ago given a similar code structure.

// FILE: SessionModel.js
import bluebird from 'bluebird';
import mongoose from 'mongoose';

// TODO: remove this redundant bit of code
// use bluebird as default promise library
mongoose.Promise = bluebird;

SessionSchema.methods.getUser = function(callback) {
  return mongoose.model('User').findById(this.user, callback);
};

@mcfarljw You are better off doing something like this:

// config.js
const bluebird = require('bluebird');
const mongoose = require('mongoose');
mongoose.Promise = bluebird;
mongoose.connect('mongodb://localhost:27017/myApp)
module.exports = { mongoose }
// SessionModel.js
const { mongoose } = require('./config')

SessionSchema.methods.getUser = function(callback) {
  return mongoose.model('User').findById(this.user, callback);
};

That way you won't have to write "mongoose.Promise = bluebird" numerous times :)

In my situation, was getting the deprecation warning when acting on sub-docs using .then() syntax, but not on parent docs. So the occasional warning made me think I had syntax problems with dealing with children docs, but it was in fact the lack of promise line in the model file as others have advised above.

Yes, it appears that setting the mongoose.Promise in the schema files where mongoose.model is exported eliminates the warning in mongoose versions 4.8 and later.

Yeah passing around the mongoose singleton as your own mutated export would get around the issue, but it's admittedly a bit of a hack.

At this point it's unclear to me as to exactly what the "proper" mongoose setup/configuration to avoid the warning is. Is this warning an issue with current mongoose versions or or is it an indication of an improper mongoose setup? Is there a recommended mongoose setup that will prevent the warning? Again, this warning only starting occurring with mongoose version 4.8.0.

I have the same problem on setting the global mongoose.

I have traced down, it can set the bluebird properly down to promise_provider but when i tried to get back the promise, it will return the ES6 one.

I just went through and added

mongoose.Promise = global.Promise

immediately following the require/import of mongoose in every source file that uses it, and although that's overkill, it took very little thinking and not very much time doing, and it did fix it completely. So, not really the biggest of deals.

It does challenge my admittedly limited knowledge of how require and import work. I was under the impression that no matter how many times you require something, you always get the same instance, so setting the promise once should be enough, you would think. So it's a bit counter-intuitive.

Hi
I have some example code that cause the problem

import mongoose from 'mongoose';

mongoose.Promise = Promise;

import Test from './test.model';

mongoose.connect(uri, options);
mongoose.connection.on('error', err => console.error(`MongoDB connection error: ${err}`));

Test.create({ name: 'Hi'})
  .then(() => Test.findOne({}))
  .then(res => res.save())
  .then(() => console.log('Done'));

(test.model is just a simple model with one field for name)

For some reason the problem first appears when doing res.save();. Without it everything works as usual.

I believe that this problem comes from babel changing the order when transpiling the code. When babel transpiles, it moves all the imports to the top. So when the test.model is imported in my example the Promise-library is still assigned to mpromise.

I'm using Node.js 6.10.0 and Mongoose 4.8.5 and I got this problem to.

I save my user object :

var newUser = User({
    login       : 'john',
    password    : 'secret',
    firstname   : 'John',
    lastname    : 'Doe',
    avatar      : 'avatar.png'
});

newUser.save(function(err){
    if(err) throw err;

    console.log('User created !');
});

And I have the same error. I tried this way :

mongoose.Promise = require('bluebird');
mongoose.connect(conf.dbpath);

And this way :

mongoose.Promise = global.Promise;
mongoose.connect(conf.dbpath);

But I have again the deprecated warning. How can I fix this ?

Howto Fix Deprecation Warning:

var mongoose = require('mongoose');

mongoose.Promise = global.Promise;
var schema = new mongoose.Schema({
 // definition
}, {
 // options
});

module.exports = mongoose.model('foobar', schema);

Yeah it works if I put this in my model. So we have to init mongoose.Promise inside each model.

I think @stevenelson74708 has an excellent point when saying At this point it's unclear to me as to exactly what the "proper" mongoose setup/configuration to avoid the warning is.

Yes, a fix would be to go back through all mongoose model files and add mongoose.Promise = global.Promise after the import, but since this issue has only cropped up recently it'd be nice to get a more concrete answer as to the intentions or causes behind it. I'm uncertain at this point whether it's an issue caused by mongoose, babel or a combination of the two.

Likely a dupe of #5030. Try upgrading to >= 4.9.1.

For the record, @bricss solution worked pretty well for me :)

At first the solution comes from @steve-p-com. Not from @bricss.
@vkarpov15 same warning with 4.9.3.
@stillesjo it's nothing with babel. The warning occurres also on nativ without Babel on Node 7.8.0.

I don't have any warnings since version 4.9.3 🌷

Even when we set mongoose.Promise = global.Promise; on every model I think it's not an _ideal_ fix right ? Why not using global.Promise as default and let users change if they want to ?

Unit testing my models. I have to include it so we don't see the warning when running tests locally or on CI.
I'm using "mongoose": "4.10.4" with node v7.10.0

@lesterzone

Just to add to this a DRY solution, set it up where you initialise the connection with teh database instead of setting inside each model.

const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://...');

seems to work

That won't necessarily work for everyone though. It depends on your code structure. If for example the file with the connection code requires models from separate source files, the way require works means that those source files will get loaded before the global promise has been set in the file containing the connection code. Those models will continue to use the default value for the promise. The safe route is simply to set the global promise in every source file that requires mongoose.

this works for me
````
import mongoose from 'mongoose';
import config from './config';
import bluebird from 'bluebird';

export default callback => {
mongoose.Promise = bluebird;
//connect to the database from the instance of the database in config file
let db = mongoose.connect(config.mongoUrl, {useMongoClient: true});
callback(db);
}
````

That's that way I'm doing it.

var colors = require('colors');
var mongo = require('mongodb');
var mongoose = require('mongoose');
mongoose.Promise = require('bluebird');

var db = mongoose.connection;

mongoose.connect('mongodb://localhost:27017/db', { useMongoClient: true })
.then(function(){
  console.log(" Connected to dbName ".green);

}).catch(err => console.error(err));

You have to use .create function that comes with mongoose rather than .save,
I changed mine and it fixes the problem

I am on 4.13.9 and this still exists. @Gilbert136 solution fixes this, strikes me as odd though. .create calls .save, so how come there is no deprecation warning then?

Was this page helpful?
0 / 5 - 0 ratings