2
votes

I'm building an app with node/express/mongo/mongoose. I've encountered an error that I can't seem to figure out and googling around has so far not been helpful.

I've created a simplistic, cat-themed example to recreate the error I'm encountering. I'm basically trying to retrieve an object by its ObjectId. I'm using the object id (as a string) that was automatically generated when I created the object.

When I navigate to the path localhost:3000/kitty/586d62878fc14d30e0ac5379 I get the following error: 'Cast to ObjectId failed for value "586d62878fc14d30e0ac5379" at path "_id" for model "Kitten"'. The offending line of code is my call to model.Kitten.findById() [see below].

As far as I can tell, the ObjectId string is valid.

I've tried casting my string object id to a mongoose object id and passing this in to findById instead of the string value, but this only produces a strange "hex is not a function" error, and besides, I am under the impression that this is unnecessary because mongoose automatically casts a valid string id to an object id.

I'm using a hosted mongodb instance (mlab).

Here is my code for reference:

Package.json:

{
  "name": "testapp",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },
  "dependencies": {
    "body-parser": "~1.15.2",
    "cookie-parser": "~1.4.3",
    "debug": "~2.2.0",
    "express": "~4.14.0",
    "jade": "~1.11.0",
    "mongodb": "^2.2.19",
    "mongoose": "^4.7.6",
    "morgan": "~1.7.0",
    "serve-favicon": "~2.3.0"
  }
}

app.js:

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var index = require('./routes/index');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', index);
app.use('/users', users);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

index.js:

var express = require('express');
var router = express.Router();
var model = require('./model');
var mongoose = require('mongoose');

/* GET home page. */
router.get('/kitty/create', function(req, res, next) {

    var fluffy = new model.Kitten({ name: 'fluffy' });

    fluffy.save(function(err, fluffy){
        if(err) return next(err);
        res.render('index', { title: 'Express' });
    });

});

router.get('/kitty/:id', function(req, res, next){

    // find kitty by id
    model.Kitten.findById(req.params.id, function(err, kitty){

        if(err) return next(err);

        if(!kitty){
            res.send('no kitty found');
        } else {
            res.send(kitty._id);
        }

    });

});

module.exports = router;

model.js:

var mongoose = require('mongoose');

mongoose.connect('mongodb://xxxxx:[email protected]:xxxxx/xxxxx');

var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {

    var kittySchema = mongoose.Schema({
        name: String
    });
    var Kitten = mongoose.model('Kitten', kittySchema);

    exports.Kitten = Kitten;

});

Any insight you can offer would be greatly appreciated.

1

1 Answers

6
votes

I was having the exact same problem. There seems to be an issue with mongoose version. I downgraded from 4.7.6 to 4.7.2 (the last version I was using before upgrading) and no more problem.

I don't know exactly in which version the problem was introduced, but based on the absence of answers when googling, maybe it's 4.7.6 (released on 2017-01-02).

Just doing

npm install --save [email protected]

will fix it for now.

Hope this helps :)

Edit: It's definitely a bug on versions after 4.7.2 https://github.com/Automattic/mongoose/issues/4867#issuecomment-270342054