The above code snippet is actually vanilla and for a cursory look everything seems to be fine.
Only when you run the code you realise the error is related to the USer.Id field for being empty.
You, just like me when I did this for the first time were expecting the mgo
framework to generate the ID if empty. For that to happen you are missing a minute detail
type User struct {
ID bson.ObjectId `bson:"_id, omitempty"`
Name string `bson:"name"`
Email string `bson:"email"`
}
Without specifying omitempty
you are essentially indicating to mgo
that you would be generating the objectId before insertion. Hence mgo steps aside to handover control. When you dont supply the ID (that you were committing to) Mongo throws back.
Contrast to that when omitempty mgo understands its empty and you no longer intend to supply a new ID. Mgo then auto generats the same.