Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"this.$__schema.paths[p].splitPath is not a function" when defining a document array using a schema from an earlier version of Mongoose #10453

Closed
lucaslimao opened this issue Jul 15, 2021 · 13 comments
Labels
developer-experience This issue improves error messages, debugging, or reporting
Milestone

Comments

@lucaslimao
Copy link

lucaslimao commented Jul 15, 2021

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

What is the current behavior?

I updated the lib version recently.
from 5.9.4 to 5.13.2
After updated I run the code, I get the following error: this.$__schema.paths[p].splitPath is not a function started.

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

code snippet

    const follower = { id: value, ...user }

    const Model = new model

    Model.followers.push(follower)

**or**

const { nModified } = await model.update(
        { user: id, 'followers.id': { $ne: follower.id } },
        {
            $push: { followers: follower },
            $inc: { count: 1 }
        }
    )

**Schema**

const mongoose = require('mongoose')
const Schema = mongoose.Schema

const User = new Schema(
    {
        name: String
    },
    {
        _id: false,
        timestamps: true
    }
)

module.exports = {
    count: {
        type: Schema.Types.Number,
        default: 0
    },
    user: {
        type: Schema.Types.ObjectId, ref: 'User'
    },
    followers: [
        User
    ]
}

**Error**

{
    "errorMessage": "this.$__schema.paths[p].splitPath is not a function",
    "errorType": "TypeError",
    "stackTrace": [
        "TypeError: this.$__schema.paths[p].splitPath is not a function",
        "    at EmbeddedDocument.Document.$__buildDoc (/home/lucas/dev/users-service/workers/node_modules/node-mongoose-repository/node_modules/mongoose/lib/document.js:490:42)",
        "    at EmbeddedDocument.Document (/home/lucas/dev/users-service/workers/node_modules/node-mongoose-repository/node_modules/mongoose/lib/document.js:133:10)",
        "    at EmbeddedDocument [as constructor] (/home/lucas/dev/users-service/workers/node_modules/node-mongoose-repository/node_modules/mongoose/lib/types/embedded.js:47:12)",
        "    at new EmbeddedDocument (/home/lucas/dev/users-service/workers/node_modules/node-mongoose-repository/node_modules/mongoose/lib/schema/documentarray.js:116:17)",
        "    at CoreDocumentArray._cast (/home/lucas/dev/users-service/workers/node_modules/node-mongoose-repository/node_modules/mongoose/lib/types/documentarray.js:109:12)",
        "    at CoreDocumentArray._mapCast (/home/lucas/dev/users-service/workers/node_modules/node-mongoose-repository/node_modules/mongoose/lib/types/core_array.js:272:17)",
        "    at Arguments.map (<anonymous>)",
        "    at CoreDocumentArray.push (/home/lucas/dev/users-service/workers/node_modules/node-mongoose-repository/node_modules/mongoose/lib/types/core_array.js:666:21)",
        "    at CoreDocumentArray.push (/home/lucas/dev/users-service/workers/node_modules/node-mongoose-repository/node_modules/mongoose/lib/types/documentarray.js:210:28)",
        "    at Object.add (/home/lucas/dev/users-service/workers/utils/handler.bucket.js:49:21)",
        "    at processTicksAndRejections (internal/process/task_queues.js:97:5)",
        "    at async Object.create (/home/lucas/dev/users-service/workers/services/followers/command/index.js:17:28)",
        "    at async /home/lucas/dev/users-service/workers/handler.followers.js:46:13",
        "    at async Promise.all (index 0)",
        "    at async create (/home/lucas/dev/users-service/workers/handler.followers.js:37:5)"
    ]
}

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

Node.js 12.18.3
Mongoose 5.13.2
Mongo 4.4

@IslandRhythms
Copy link
Collaborator

Check that you do not have multiple versions of mongoose installed

@lucaslimao
Copy link
Author

lucaslimao commented Jul 21, 2021

Hey @IslandRhythms .
No, I don't have multiple versions of mongoose.
I noticed that the error appears when using a new Schema, if I remove the new Schema, the error doesn't appear.

example:

const User = {
        name: String
}

module.exports = {
    count: {
        type: Schema.Types.Number,
        default: 0
    },
    user: {
        type: Schema.Types.ObjectId, ref: 'User'
    },
    followers: [
        User
    ]
}

@vkarpov15 vkarpov15 added this to the 5.13.4 milestone Jul 28, 2021
@vkarpov15 vkarpov15 added the needs repro script Maybe a bug, but no repro script. The issue reporter should create a script that demos the issue label Jul 28, 2021
@vkarpov15 vkarpov15 modified the milestones: 5.13.4, 5.13.5, 5.13.6 Jul 28, 2021
@vkarpov15
Copy link
Collaborator

@lucaslimao this does look indicative of having multiple versions of Mongoose installed. My best guess is that /home/lucas/dev/users-service/workers has a distinct version of Mongoose from /home/lucas/dev/users-service/workers/node_modules/node-mongoose-repository and that's what is causing the issue.

Can you please try running npm list mongoose and paste the output?

@vkarpov15 vkarpov15 changed the title this.$__schema.paths[p].splitPath is not a function "this.$__schema.paths[p].splitPath is not a function" when defining a document array using a schema from an earlier version of Mongoose Aug 9, 2021
@vkarpov15 vkarpov15 added developer-experience This issue improves error messages, debugging, or reporting and removed needs repro script Maybe a bug, but no repro script. The issue reporter should create a script that demos the issue labels Aug 9, 2021
@gregorybellencontre
Copy link

Hello :)
I have a weird error with Mongoose, based on the fix that has been made following this issue.

Schema for array path `credits` is from a different copy of the Mongoose module. Please make sure you're using the same version of Mongoose everywhere with `npm list mongoose`.

I'm using schemas defined in a different repository, both repositories have Mongoose 6.1.2
I checked the yarn.lock and node_modules to be 100% sure, and I only have one version of Mongoose.

After some tests with Mongoose, I figured out that I can solve the problem by removing this throw :
https://github.com/Automattic/mongoose/blob/master/lib/schema.js#L952

I don't have any other error.

I would be interested to have your thoughts about this case.

const TitleSchema = new mongoose.Schema<Title>(
  {
    title: {
      type: String
    },
    credits: [CreditSchema]
  }
)
const CreditSchema = new mongoose.Schema<Credit>({
  personId: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'persons',
    key: 'person',
    required: [true, 'ERROR_REQUIRED'],
  },
  jobId: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'jobs',
    key: 'job',
    required: [true, 'ERROR_REQUIRED'],
  }
})

Thanks !

@vkarpov15
Copy link
Collaborator

@gregorybellencontre can you please paste the output of npm list | grep "mongo" or whatever the yarn equivalent is?

@gregorybellencontre
Copy link

@vkarpov15 Here's the result of the yarn link | grep "mongo" :

│  ├─ [email protected]
│  ├─ [email protected]
├─ [email protected]
├─ [email protected]
│  ├─ mongodb-connection-string-url@^2.3.2
├─ [email protected]
│  ├─ [email protected]

@vkarpov15
Copy link
Collaborator

So you do have 2 copies of Mongoose after all, they're just the same version. Where does the nested version of mongoose come from?

@gregorybellencontre
Copy link

Indeed, I'm using a personal NPM package where I store some Mongoose schemas.
So I had a copy of Mongoose in this NPM package + another copy in my main repository.
I don't know how, but I finally managed to remove the mongoose copy from the node_modules of my schemas package.
It's working fine now.
Thanks for your help.

@vkarpov15
Copy link
Collaborator

If you have an npm package that stores Mongoose schemas, we'd recommend listing Mongoose in peerDependencies.

@mikkixlisa
Copy link

I am facing the same issue but only when using the 'remote' schema in an Array.

I defined a Tag schema in a separate npm package:

export const TagSchemaDefinition: SchemaDefinition<SchemaDefinitionType<Tag>> = {
  color: String,
  name: { required: true, type: String },
  slug: { required: true, type: String },
};

export const TagSchema = new Schema<Tag>(TagSchemaDefinition, { _id: false });

When trying to use this schema in my main repo like this:

const SomeSchema = new Schema<SomeDocument, SomeModel>(
  {
    ...
    tags: [TagSchema],
    ...
  },
  { ... },
);

I am getting an error:

TypeError: Schema for array path `tags` is from a different copy of the Mongoose module. 
Please make sure you're using the same version of Mongoose everywhere with `npm list mongoose`.

When using it as a single item, it works fine:

const SomeSchema = new Schema<SomeDocument, SomeModel>(
  {
    ...
    tag: TagSchema,
    ...
  },
  { ... },
);

Output of npm list | grep "mongo":

├── @private/[email protected]
├── [email protected]
└── [email protected]

Output of npm list mongoose:

├─┬ @private/[email protected]
│ └── [email protected] deduped
└── [email protected]

In @private/mongoose-shared I am listing mongoose as peerDependency.

@vkarpov15 vkarpov15 reopened this Jan 7, 2022
@vkarpov15 vkarpov15 modified the milestones: 5.13.6, 6.1.9 Jan 7, 2022
@sbland
Copy link

sbland commented Jan 11, 2022

I get this issue after updating from 5.12.3 to 5.13.14.
I only get the error when using jest.
Output of npm list | grep "mongo"

Edit:
This seemed to be caused by manually setting the _id. This worked prior to [email protected] but from docs it looks like it should have failed.

const newDoc = new Model({ 
     _id: mongoose.Types.ObjectId('customid'),
});
const insertedDoc = await newDoc.save();

@vkarpov15 vkarpov15 modified the milestones: 6.2.2, 6.2.3, 6.2.6 Feb 16, 2022
@vkarpov15 vkarpov15 modified the milestones: 6.2.6, 6.2.7 Mar 11, 2022
@vkarpov15
Copy link
Collaborator

We'll try a different approach with 50b670c. Our approach of throwing an error if you pass something that isn't strictly instanceof Schema might be a bit too coarse. We'll instead use clone() to try to convert the schema instance to the calling Mongoose instance's Schema class.

As a workaround, you can always wrap your shared schema in a new Schema() call:

const SomeSchema = new Schema<SomeDocument, SomeModel>(
  {
    ...
    tags: [new Schema(TagSchema)],
    ...
  },
  { ... },
);

This should work, even if TagSchema is an instance of a different Mongoose module's Schema class.

vkarpov15 added a commit that referenced this issue Mar 13, 2022
@vkarpov15
Copy link
Collaborator

On second thought, we're just going to improve the error message to suggest using new Schema() to correct the error. We don't want to necessarily always try to convert a schema from a potentially different version of Mongoose to the current version's implicitly. That could lead to surprising behavior. At least, with the error, devs will be aware of the issue, and hopefully check that new Schema(TagSchema) works as expected for them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
developer-experience This issue improves error messages, debugging, or reporting
Projects
None yet
Development

No branches or pull requests

6 participants