Mongoose: Unique index validation error not throwing

Created on 27 Nov 2012  路  12Comments  路  Source: Automattic/mongoose

I'm using this schema with latest npm mongoose:

var schema = new Schema({

    _id: Schema.ObjectId,
    email: {type: String, required: true, unique: true}

});

If I try to save a email that is already in db, I expect to get a ValidationError like if a required field is omitted. However this is not the case, I get a MongoError: E11000 duplicate key error index.

Which is not a validation error (happens even if I remove the unique:true).

Most helpful comment

For anyone interested, I鈥檝e added a plugin which checks the DB prior to saving and throws a Mongoose validation error if any of your unique constraints will be violated:
https://github.com/blakehaswell/mongoose-unique-validator

All 12 comments

Setting unique: true creates an unique index in MongoDB. MongoError: E11000 duplicate key error index is not a Mongoose validation error, it comes from MongoDB.

how can i catch this error?

doc.save(function (err) {
  // handle err
})

i tryed it and the error didin't bubbled.
for now i'm using this function to do validation:

/**
 * Unique Validation
 * @param {Schema} schema The schema to witch validate.
 * @param {Model} model The model to perform searches.
 * @param {String} field The field name to search for duplicated entries.
 * @throws {E11000} Duplicate key.
 */
function uniqueValidator(schema, model, field) {
    schema.pre('save', function(next){
        var toValidate = {};
        toValidate[field] = this[field];
        model.findOne(toValidate, field, function(err, res){
            if (err) {
                next(err);
            } else if (res) {
                err = new Error('Duplicate key.');
                err.code = 'E11000';
                next(err);
            } else {
                next();
            }
        });
    });
}

it's not best practices but is working. i just wanted to know if there was some "cleaner"/best way to do this. thanks.
ps: i'm using updated versions of both mongo and mongoose

check the indexes that exist in your collection to see if the unique index exists.

  1. open the mongo shell
  2. use yourDatabase
  3. db.yourCollection.getIndexes()

You should see all indexes that exist on your collection. Check to see if your unique index exists.

If it does, something is very wrong.

If it doesn't (more likely), there are probably duplicate values in the collection already which will prevent a unique index from being created. You can check this by adding a listener to your models index event and checking for errors:

var schema = Schema(..);
var YourModel = mongoose.model('YourModel', schema);
YourModel.on('index', function (err) {
  if (err) console.error(err);
})

http://mongoosejs.com/docs/api.html#model_Model.ensureIndexes
http://mongoosejs.com/docs/guide.html#indexes

thanks. that's what heppened, first i added non-unique values, and then changed the code adding unique: true to them.
sorry for the question, but how do i abort the save operation?
it's still saving on the db.

I don't understand your question.

as there is a duplicate key and it have to be unique, how do i stop the saving operation so it isin't saved, or what alternative should i try?

I think it would be great if the unique error was thrown the same way of other validators.

Mongoose could check if the error code is 11001 (http://www.mongodb.org/about/contributors/error-codes/) and then call something like: doc.invalidate(path, "unique").

I tried doing this with schema.post('save', ...) but it seems that no post handlers are called on error.

sorry, the error was mine.
i dumped the database and started fresh _with_ the unique:true setting set, the error was thrown in my save operation and the object didn't got saved (the behavior i was expecting).
i'm really sorry for the inconvenience.

For anyone interested, I鈥檝e added a plugin which checks the DB prior to saving and throws a Mongoose validation error if any of your unique constraints will be violated:
https://github.com/blakehaswell/mongoose-unique-validator

I had this issue and it was due to already existing duplicate values in my index (as pointed out in aheckmann's comment on Feb 1, 2013). I was reading from here http://mongoosejs.com/docs/api.html#schematype_SchemaType-required where it mentions the error, but fails to mention about already exiting duplicates preventing the uniques index from being created in the first place. Might be worth updating the doc to mention this too!

Was this page helpful?
0 / 5 - 0 ratings