No está consultando un ObjectId, no importa cuánto crea que lo es. Está consultando el ObjectId codificado como una cadena hexadecimal, que no la misma cosa. Encasilla correctamente y probablemente tendrás mucho más éxito.
Editado para elaborar, desde un mongo (JS) shell REPL:
> // Omitting the _id, or generating a new one, are equivalent during insert.
> db.foo.insert({_id: ObjectId()})
WriteResult({ "nInserted" : 1 })
> db.foo.find() // As expected, we get back our _real_ ObjectId value.
{ "_id" : ObjectId("5c9cfab873724727778c0730") }
> // Can we "insert the record again" using a string version of the ID?
> db.foo.insert({_id: "5c9cfab873724727778c0730"})
WriteResult({ "nInserted" : 1 }) // Sure as heck can! No unique violation!
> db.foo.find() // Because THESE ARE NOT THE SAME
{ "_id" : ObjectId("5c9cfab873724727778c0730") }
{ "_id" : "5c9cfab873724727778c0730" }
Después de nuestra discusión en el IRC, parece haber dificultades para comprender los "términos de búsqueda" en las respuestas que le están dando. Busque aquí en StackOverflow (o Google, o DDG) "mongoose typecast ObjectId" (sin comillas; o simplemente "mongoose ObjectId"...) y encontrará muchas respuestas, ya que este es un problema particularmente común para los usuarios de Mongoose.