43

I have a method to find a document in my database based on its ObjectID:

      console.log('id: ' + id + ' type: ' + typeof id);
      collection.findOne({'_id':new ObjectID(id)}, function(error,doc) {
        if (error) {
          callback(error);
        } else {
           callback(null, doc);
        }
      });

When I run it I get the following error:

/myPath/node_modules/monk/node_modules/mongoskin/node_modules/mongodb/lib/mongodb/connection/base.js:245
    throw message;      
          ^
Error: Argument passed in must be a single String of 12 bytes or a string of 24 hex characters
at new ObjectID (/myPath/node_modules/mongodb/node_modules/bson/lib/bson/objectid.js:38:11)
at /myPath/collectionDriver.js:134:41

This refers to the collection.findOne() line above.

The console log I have before that call outputs the id as a string of 24 hex characters:

id: "55153a8014829a865bbf700d" type: string

Before this I convert the id from an object to a string using JSON.stringify() but it appears to work successfully as shown in my console.log.

Running db.myCollection.findOne({_id : ObjectId("55153a8014829a865bbf700d")}) in Robomongo brings back the expected result.

Carasel
  • 2,740
  • 5
  • 32
  • 51

15 Answers15

39

The id that was passed in to my function was already an object ID in this case, so did not need a new ObjectID to be created from it.

When ObjectIDs are logged out to the console they appear as hex strings, rather than ObjectID("hexString"), so I thought I needed to convert it to do the find, but it was already in the format that I needed.

Carasel
  • 2,740
  • 5
  • 32
  • 51
  • 1
    Thanks for your solution. I'm running into this issue as well, however, if I remove ObjectId(...) I get an Invalid Arg Type Error. If I leave the object Id, it works, but I get this error message every time. Any thoughts on this? – user3230279 Nov 18 '19 at 14:40
4

Try this:

var hex = /[0-9A-Fa-f]{6}/g;
id = (hex.test(id))? ObjectId(id) : id;
collection.findOne({'_id':new ObjectID(id)}, function(error,doc) {
  if (error) {
    callback(error);
  } else {
    callback(null, doc);
  }
});
FelixSFD
  • 6,052
  • 10
  • 43
  • 117
Martín Mtz
  • 41
  • 1
  • 1
3

In my case, this worked:

var myId = JSON.parse(req.body.id);
    collection.findOne({'_id': ObjectID(myId)}, function(error,doc) {
    if (error) {
      callback(error);
    } else {
       callback(null, doc);
    }
});

Don't forget to include at the beginning:

var ObjectId = require('mongodb').ObjectID;
Tunaki
  • 132,869
  • 46
  • 340
  • 423
profesoralex
  • 417
  • 1
  • 3
  • 10
2

Yeah, I just spent thirty minutes baffled by this. If anyone finds themselves here, first check if you even need to convert to ObjectID in the first place. Like OP, I forgot that the hexstring is logged as just that - a hexstring.

struensee
  • 566
  • 8
  • 17
1

Try out ObjectID(id) instead of new ObjectID(id)

Talgat Medetbekov
  • 3,741
  • 1
  • 19
  • 26
  • Thanks for the suggestion, but this does not change the outcome. – Carasel May 05 '15 at 11:14
  • I just tried following code nad it recognizing hexstring: `var ObjectID = require('mongodb').ObjectID;ObjectID.createFromHexString('55153a8014829a865bbf700d') 55153a8014829a865bbf700d` – Talgat Medetbekov May 05 '15 at 11:21
  • Yeah, works for me like that too, but not with my input, which apparently isn't the hex string it appears to be. – Carasel May 05 '15 at 16:01
1

I got the same error. Later I found that I have included a whitespace while sending the values to the server.

<input type="checkbox" name="checkbox" value="<%= item._id %>" onchange="this.form.submit()" />
  

In the value attribute I had typed as value="<%= item._id %> " . A whitespace after the ID. It caused to that error. After I removed it(value="<%= item._id %>" ), the problem solved.

The below code worked for me.

item.findOne({'_id':id} , (err)=>{

if(err){
  console.log(err);
}
else{
  console.log("Item Found");
}

});

Lasith Eranga
  • 38
  • 1
  • 4
1

Actually the Id you are fetching have whitespaces in it so adding trim() to your id will work

const id = (req.params.id).trim();
const result =  await deleteOne({_id:new mongodb.ObjectId(id)});

while using this code keep in mind that your function should be async and mongodb should have been imported.

0

I was having the same issue but trimming the productId passed to ObjectId() worked for me

Earlier:

    const objectId = new ObjectID(productId);
    product = await db?.collection('products').find({ _id: objectId }).next();

Now:

    const objectId = new ObjectID(productId.trim());                                       
    product = await db?.collection('products').find({ _id: objectId }).next();
0

I found the source of this,

make sure the value must not have any whitespace,

you can use const ID = id.trim(); then use ObjectId(ID)

Thanks Happy Coding

0

Argument passed in must be a string of 24 hex characters if you are getting this error then. just do this

use .trim() to delete any extra character usually a space is added to the id. and it becomes 25 hex charater . so instead of _id = yourId; use _id = yourId.trim()

0

collection.find({ _id: { $in: req.body.map(pd => ObjectId(pd)) } })

use map() on the res.body -- it works for me.

C. Peck
  • 3,641
  • 3
  • 19
  • 36
0
const ID = (req.body.id).trim();

Worked for me, actually (req.body.id) adds an extra space to the ID variable.

After I used .trim() method it worked.

4b0
  • 21,981
  • 30
  • 95
  • 142
0

I have tried all answers. But it doesn't work for me. Maybe if you are getting params with express. It's worked for me. Try this;

var MongoClient = require('mongodb').MongoClient;
const {ObjectId} = require('mongodb');

app.get('/:id', (req, res) => {

var reqId = req.params.id
var query = reqId.toString()


MongoClient.connect(url, function(err, db) {
    if (err) throw err;
    var dbo = db.db("AllDB");
    dbo.collection("Events").findOne({_id: ObjectId(query)}, function(err, result) {
        if (err) throw err;
        res.send(result)
        db.close();
      });
});

})

Update :

Hey, I give same error again, and I notice new solution. If your code like this:

app.get('/', (req, res) => {
    res.send('TEST')
})


app.get('/:id', (req, res) => {

   var reqId = req.params.id
   var query = reqId.toString()

})

Could you try change your get request route. Maybe such as app.get('/findid/:id)

It worked for me. I was searching again and i found this way.

Thanks, Regards.

Mert
  • 39
  • 4
0

Sometimes clearing your local storage could be the solution to this error. From 'inspect' just go to Application>local storage and select the URL. Then press the 'clear all' sign. It worked for me.

0

In my case when I have used this const product = await Product.findOne({'_id':id}), it solved the error

const {_id, name, description}=product||{}




export const read = async (req, res) => {
  try {
    //const product = await Product.findOne({ slug: req.params.slug })
    const product = await Product.findOne({'_id':id})
    
      .select("-photo")
      .populate("category");

    res.json(product);
  } catch (err) {
    console.log(err);
  }
};

enter image description here