Automattic / mongoose

MongoDB object modeling designed to work in an asynchronous environment.
https://mongoosejs.com
MIT License
26.96k stars 3.84k forks source link

TypeError: Cannot create property 'excluded' on string 'modify' #10825

Closed chaeron closed 3 years ago

chaeron commented 3 years ago

We have large, complex, highly nested mongoose schemas. They work fine on mongoose v5.13.7.

Upgrading to v6.0.8 we get the following error when saving a document:

TypeError: Cannot create property 'excluded' on string 'modify'

May be related or similar to https://duckduckgo.com/?t=ffab&q=mongoos+TypeError%3A+Cannot+create+property+%27excluded%27+on+string+%27modify%27&ia=web

And no.....I can't provide a test case at this time. Too busy and our schemas are too complex/proprietary to our healthcare app to try and create a replicable test scenario. Sorry.

Trace log, if it helps:

TypeError: Cannot create property 'excluded' on string 'modify' at setDottedPath (/home/andrzej/Dropbox/Shore/TGLN/dev/migration/node_modules/mongoose/lib/helpers/path/setDottedPath.js:15:13) at flattenObjectWithDottedPaths (/home/andrzej/Dropbox/Shore/TGLN/dev/migration/node_modules/mongoose/lib/helpers/path/flattenObjectWithDottedPaths.js:19:7) at flattenObjectWithDottedPaths (/home/andrzej/Dropbox/Shore/TGLN/dev/migration/node_modules/mongoose/lib/helpers/path/flattenObjectWithDottedPaths.js:23:5) at flattenObjectWithDottedPaths (/home/andrzej/Dropbox/Shore/TGLN/dev/migration/node_modules/mongoose/lib/helpers/path/flattenObjectWithDottedPaths.js:23:5) at flattenObjectWithDottedPaths (/home/andrzej/Dropbox/Shore/TGLN/dev/migration/node_modules/mongoose/lib/helpers/path/flattenObjectWithDottedPaths.js:23:5) at flattenObjectWithDottedPaths (/home/andrzej/Dropbox/Shore/TGLN/dev/migration/node_modules/mongoose/lib/helpers/path/flattenObjectWithDottedPaths.js:23:5) at flattenObjectWithDottedPaths (/home/andrzej/Dropbox/Shore/TGLN/dev/migration/node_modules/mongoose/lib/helpers/path/flattenObjectWithDottedPaths.js:23:5) at $applyDefaultsToNested (/home/andrzej/Dropbox/Shore/TGLN/dev/migration/node_modules/mongoose/lib/document.js:536:3) at model.$set (/home/andrzej/Dropbox/Shore/TGLN/dev/migration/node_modules/mongoose/lib/document.js:1106:9) at model.Document (/home/andrzej/Dropbox/Shore/TGLN/dev/migration/node_modules/mongoose/lib/document.js:148:12)

IslandRhythms commented 3 years ago

https://mongoosejs.com/docs/migrating_to_6.html

See if maybe mongoose 6 breaks something your code is doing

chaeron commented 3 years ago

I checked the list of v6 breaking changes.....none of them apply to what we're doing.

It's a bug. ;-)

IslandRhythms commented 3 years ago

This is how I was able to reproduce your error message. Scan your code for something that is causing this to happen.

import * as mongoose from 'mongoose';

interface User {
  name: string;
  email: string;
  avatar?: string;
}

// 2. Create a Schema corresponding to the document interface.
const schema = new mongoose.Schema<User>({
  name: { type: String, required: true },
  email: { type: String, required: true },
  avatar: String
});

// 3. Create a Model.
const UserModel = mongoose.model<User>('User', schema);

run().catch(err => console.log(err));

async function run(): Promise<void> {
  await mongoose.connect('mongodb://localhost:27017/test');
  await mongoose.connection.dropDatabase();
  const doc = new UserModel({
    name: 'modify',
    email: 'bill@initech.com',
    avatar: 'https://i.imgur.com/dM7Thhn.png'
  });
  await doc.save();
  const newDoc = await UserModel.findById({_id: doc._id});
  let name = 'name';
  let excluded = 'excluded';
  newDoc[name][excluded] = 'hi'; // this is what throws the error
// newDoc.name = {excluded: 'excluded'} // throws a cast error
  await newDoc.save();
}
IslandRhythms commented 3 years ago

@chaeron https://mongoosejs.com/docs/migrating_to_6.html#removed-nested-path-merging You're sure this isn't happening? The code that was changed points to the stack trace you gave.

chaeron commented 3 years ago

As I had mentioned, with no changes to our application code.....everything works with v5.13.7.....when we upgrade Mongoose to v6.0.8, we get the error.

So it's not our code!

vkarpov15 commented 3 years ago

I haven't been able to repro this as well as I'd like. The below script roughly repros this fairly accurately in terms of error message and stack trace, but based on the fact that modify and excluded are property names that Mongoose uses, I'm not sure this is an accurate picture of what's happening.

'use strict';

const mongoose = require('mongoose');

mongoose.set('debug', true);

const { Schema } = mongoose;

run().catch(err => console.log(err));

async function run() {
  await mongoose.connect('mongodb://localhost:27017/test', {
  });

  await mongoose.connection.dropDatabase();

  const schema = new Schema({ nested: { prop: String } });
  const Test = mongoose.model('Test', schema);

  const doc = new Test({ nested: { prop: 'modify', 'prop.excluded': 'foo' } });
  await doc.save();
  console.log('done');
}

Stack trace:

TypeError: Cannot create property 'excluded' on string 'modify'
    at setDottedPath (/home/val/Workspace/MongoDB/mongoose/lib/helpers/path/setDottedPath.js:15:13)
    at flattenObjectWithDottedPaths (/home/val/Workspace/MongoDB/mongoose/lib/helpers/path/flattenObjectWithDottedPaths.js:19:7)
    at $applyDefaultsToNested (/home/val/Workspace/MongoDB/mongoose/lib/document.js:553:3)
    at model.$set (/home/val/Workspace/MongoDB/mongoose/lib/document.js:1127:9)
    at model.Document (/home/val/Workspace/MongoDB/mongoose/lib/document.js:158:12)
    at model.Model (/home/val/Workspace/MongoDB/mongoose/lib/model.js:106:12)
    at new model (/home/val/Workspace/MongoDB/mongoose/lib/model.js:4763:15)
    at run (/home/val/Workspace/MongoDB/troubleshoot-mongoose/gh-10825.js:20:15)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)

I added a fix to improve the error message in the repro script, and hopefully fix the issue in your case.

chaeron commented 3 years ago

Cool.....any idea what version of Mongoose will have the fix in it?

I'll be sure to test it out when it is deployed....

Thanks!

vkarpov15 commented 2 years ago

@chaeron we're releasing 6.0.13 now, sorry for the delay!

chaeron commented 2 years ago

6.0.13 did the trick.....fixed the bug and we've updated our application to the latest Mongoose Version.

Thanks Valeri!