Automattic / mongoose

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

TypeError: Cannot create property in mongoose\lib\helpers\path\setDottedPath with nested arrays #10935

Closed mjfwebb closed 2 years ago

mjfwebb commented 3 years ago

Do you want to request a feature or report a bug?

Bug

What is the current behavior?

[2021/10/26 20:35:00.973] [WARN]  TypeError: Cannot create property 'actionEffects' on string 'n'
    at setDottedPath (F:\...\node_modules\mongoose\lib\helpers\path\setDottedPath.js:9:17)
    at flattenObjectWithDottedPaths (F:\...\node_modules\mongoose\lib\helpers\path\flattenObjectWithDottedPaths.js:19:7)
    at flattenObjectWithDottedPaths (F:\...\node_modules\mongoose\lib\helpers\path\flattenObjectWithDottedPaths.js:23:5)
    at flattenObjectWithDottedPaths (F:\...\node_modules\mongoose\lib\helpers\path\flattenObjectWithDottedPaths.js:23:5)
    at flattenObjectWithDottedPaths (F:\...\node_modules\mongoose\lib\helpers\path\flattenObjectWithDottedPaths.js:23:5)
    at flattenObjectWithDottedPaths (F:\...\node_modules\mongoose\lib\helpers\path\flattenObjectWithDottedPaths.js:23:5)
    at flattenObjectWithDottedPaths (F:\...\node_modules\mongoose\lib\helpers\path\flattenObjectWithDottedPaths.js:23:5)
    at flattenObjectWithDottedPaths (F:\...\node_modules\mongoose\lib\helpers\path\flattenObjectWithDottedPaths.js:23:5)
    at flattenObjectWithDottedPaths (F:\...\node_modules\mongoose\lib\helpers\path\flattenObjectWithDottedPaths.js:23:5)
    at flattenObjectWithDottedPaths (F:\...\node_modules\mongoose\lib\helpers\path\flattenObjectWithDottedPaths.js:23:5) 

If the current behavior is a bug, please provide the steps to reproduce.

I am struggling to reproduce this in a minimal code reproduction since I don't know how to manually invoke the usage of setDottedPath. The invocation occurs when I push something onto an existing array. Hopefully, the following information suffices.

When debugging, I see the following function parameters being sent into function setDottedPath(obj, path, val) {:

obj is

{
  roundNumber: 'init',
  _id: 'init',
  turnOrder: 'init',
  turns: 'init',
  combatantsStats: 'init',
  __v: 'init',
  combatId: 'init',
  'combatantsStats.1': 'modify',
  nextTurn: { id: 'init', type: 'init', action: 'init' }
}

path is combatantsStats.1.actionEffects.0

val is modify

With these three parameters, I consistently crash on line 12 of setDottedPath.js (cur = cur[part];).

My related schema is not too complex, but simply put it is nested arrays. Here is a very trimmed down version of it (For clarity: in my earlier example of obj I included some omitted properties):

const CombatRoundSchema = new Schema({
  combatantsStats: [
    {
      actionEffects: [
        {
          count: { type: Number },
          type: { type: Number },
        },
      ],
    },
  ],
});

What is the expected behavior?

No crash and setDottedPath handles nested arrays.

What are the versions of Node.js, Mongoose and MongoDB you are using? Note that "latest" is not a version.

Node: 16.6.1 mongodb: 4.1.2 mongoose: 6.0.12

IslandRhythms commented 3 years ago

Provide the code that is triggering that error. If you don't want to share that code specifically because it is to much, you can provide an example using dummy data and what not that is more direct.

IslandRhythms commented 3 years ago

@mjfwebb modify this script to demonstrate your issue.


const mongoose = require('mongoose');

(async function () {
  await mongoose.connect('mongodb://localhost:27017')
  await mongoose.connection.dropDatabase();

  const someSchema = new mongoose.Schema({
    array1: [{
        array2: [
            {
                count: Number,
                type: {type: Number}
            }
        ]
    }]
  });
  const Test = mongoose.model('Test', someSchema)
  await Test.create({
      array1: [{
          array2: [{
              count: 1,
              type: 4
          }]
      }]
  });

  console.log('done');
})();
mjfwebb commented 2 years ago

Sorry about the lack of response. I'm finding this incredibly difficult to reproduce minimally. I suspect this might actually be fixed by the changes in https://github.com/Automattic/mongoose/commit/cd277a79feb49e1c0c252121801b115afeffc6d0

To circumvent the problem, I had to ensure I used the plain old javascript version of the document through the toObject() method.

When this fix is released I'll try again in my main code repo and hopefully either report that it's fixed or at least provide better information.

mjfwebb commented 2 years ago

@vkarpov15 This issue was fixed in 6.0.13. I am confident it was fixed by the check https://github.com/Automattic/mongoose/commit/cd277a79feb49e1c0c252121801b115afeffc6d0#diff-38b9a0f8cf7c0329e7ab13ce45b2fb895d6d21943ea97eea40114442893622ccR16-R19