I'm creating a todos app with MERN stack, and in an attempt to create personal todos for each user, I found this error:
MongoServerError: E11000 duplicate key error collection: Todos-APP.todos index: _id_ dup key: { _id: ObjectId('6201a648189af9a06ac75ca1') }
at C:\Users\Administrador\Documents\GitHub\todos-app\server\node_modules\mongodb\lib\operations\insert.js:51:33
at C:\Users\Administrador\Documents\GitHub\todos-app\server\node_modules\mongodb\lib\cmap\connection_pool.js:272:25
at handleOperationResult (C:\Users\Administrador\Documents\GitHub\todos-app\server\node_modules\mongodb\lib\sdam\server.js:370:9)
at MessageStream.messageHandler (C:\Users\Administrador\Documents\GitHub\todos-app\server\node_modules\mongodb\lib\cmap\connection.js:479:9)
at MessageStream.emit (node:events:390:28)
at processIncomingData (C:\Users\Administrador\Documents\GitHub\todos-app\server\node_modules\mongodb\lib\cmap\message_stream.js:108:16)
at MessageStream._write (C:\Users\Administrador\Documents\GitHub\todos-app\server\node_modules\mongodb\lib\cmap\message_stream.js:28:9)
at writeOrBuffer (node:internal/streams/writable:389:12)
at _write (node:internal/streams/writable:330:10)
at MessageStream.Writable.write (node:internal/streams/writable:334:10) {
index: 0,
code: 11000,
keyPattern: { _id: 1 },
keyValue: {
_id: ObjectId {
[Symbol(id)]: Buffer(12) [Uint8Array] [
98, 1, 166, 72, 24,
154, 249, 160, 106, 199,
92, 161
]
}
}
}
I have well-founded suspicions that the problem arises because in my Todo Schema, I have a field 'owner' which gets populated with the client's _id from MongoDB (the client that sent the request to create the new todo):
const mongoose = require('mongoose');
const TodoSchema = new mongoose.Schema({
_id: {
type: mongoose.Types.ObjectId,
default: mongoose.Types.ObjectId()
},
owner: {
type: mongoose.Types.ObjectId,
ref: 'User'
},
title: {
type: String,
required: true
},
description: {
type: String,
required: true
},
isCompleted: {
type: Boolean,
required: true
}
});
module.exports = mongoose.model('Todo', TodoSchema);
Now, this is how the server is handling the request:
// Create Todo
router.post('/createTodo', async (req, res) => {
const { ownerName, title, description, isCompleted } = req.body;
if(!title || !description || isCompleted === null || ownerName === null) return res.status(400).send();
const owner = await User.findOne({ username: ownerName }).exec();
const existingTodo = await Todo.findOne({ owner: owner._id, title: title }).exec();
if(existingTodo) return res.status(409).send();
try {
const todo = new Todo({
owner: owner._id,
title,
description,
isCompleted
})
todo.save();
res.status(200).send();
} catch (error) {
console.error(`ERROR: ${error}`);
res.status(409).end();
}
});
I'd like to add that I've noticed that once I log in, I can successfully create a new todo, but if I try to create another one within the same session, it throws that error, but if the session expires and I log in again, then I can create another new todo; just one todo per session.
CodePudding user response:
Try to remove explicitly adding _id
to schema with value of mongoose.Types.ObjectId()
. Remove these lines from schema definition.
_id: {
type: mongoose.Types.ObjectId,
default: mongoose.Types.ObjectId()
},
Mongo will create unique _id
by default. To create ObjectId
with Mongoose, I think you should use new mongoose.Types.ObjectId()
. So maybe you are missing new
keyword.