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

Schemas in separate project with arrays causes "Schema for array path is from a different copy of the Mongoose module." #13275

Closed
2 tasks done
rndfm opened this issue Apr 14, 2023 · 9 comments · Fixed by #13441
Assignees
Milestone

Comments

@rndfm
Copy link

rndfm commented Apr 14, 2023

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the bug has not already been reported

Mongoose version

7.0.3

Node.js version

18.13.0

MongoDB server version

6.0.5

Typescript version (if applicable)

No response

Description

I have my schemas defined in a separate npm package as they are going to be used be at couple of different services.

When using an array path in the first level i get the following error:
"TypeError: Schema for array path products 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. If you are still getting this error, please add new Schema() around the path: products: new Schema(...)"

I tried adding the new Scheme(..) thing. This makes the error message disappear but when i try to new up the model it fails there instead.

BUT. If i comment out the "if and throw" in schema.js: 1276, it works as expected.

The strange thing is. I have another array that works without any errors. But it's on "level 2". Eg. there's another object path before it.

My schema is quite simple:

import { Schema } from "mongoose";
import productSchema from "./Product.js";

const companySchema = new Schema({
	id: String,
	name: String,
	image: String,
	products: [new Schema(productSchema)]
});

export default companySchema;
import { Schema } from 'mongoose';

const productSchema = new Schema({
	id: String,
	name: String
});

export default productSchema;

If i change products to a single(non array) item in the company it works just fine.

My more complex scenario that actually works is a three level deep subDocument.

First level:

import { Schema } from "mongoose";
import consumptionDataSchema from "./ConsumptionData.js";

const userSchema = new Schema({
	name: String,
	email: String,
	image: String,
	consumptionData: consumptionDataSchema
});

export default userSchema;

Second level:

import { Schema } from "mongoose";
import meteringPointSchema from "./MeteringPoint.js";

const consumptionDataSchema = new Schema({
	authorized: Boolean,
	meteringPoints: [meteringPointSchema]
});

export default consumptionDataSchema;

Third level:

import { Schema } from "mongoose";

const meteringPointSchema = new Schema({
	id: String,
	type: String,
	name: String,
	rawData: Object
});

export default meteringPointSchema;

In my shared/common package I am listing mongoose as peerDependency.

All the packages has mongoose version 7.0.3

Steps to Reproduce

I have created a demo repo that shows the problem:

https://github.com/rndfm/mongoose-schema-error

Try and run the apps with:
node level1app.js
node level2app.js

For the level 1 app I get the following error:

PS C:\repos\mongoose-schema-error\app> node app.js
C:\repos\mongoose-schema-error\app\node_modules\mongoose\lib\schema.js:1277
        throw new TypeError('Schema for array path `' + path +
              ^

TypeError: Schema for array path `products` 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`. If you are still getting this error, please add `new Schema()` around the path: products: new Schema(...)
    at Schema.interpretAsType (C:\repos\mongoose-schema-error\app\node_modules\mongoose\lib\schema.js:1277:15)
    at Schema.path (C:\repos\mongoose-schema-error\app\node_modules\mongoose\lib\schema.js:1033:27)
    at Schema.add (C:\repos\mongoose-schema-error\app\node_modules\mongoose\lib\schema.js:697:12)
    at merge (C:\repos\mongoose-schema-error\app\node_modules\mongoose\lib\helpers\schema\merge.js:12:6)
    at Schema.add (C:\repos\mongoose-schema-error\app\node_modules\mongoose\lib\schema.js:628:5)
    at new Schema (C:\repos\mongoose-schema-error\app\node_modules\mongoose\lib\schema.js:134:10)
    at Mongoose.model (C:\repos\mongoose-schema-error\app\node_modules\mongoose\lib\index.js:538:14)    at file:///C:/repos/mongoose-schema-error/app/app.js:7:1
    at ModuleJob.run (node:internal/modules/esm/module_job:194:25)

Node.js v18.13.0

For the level 2 app it works just fine.

Expected Behavior

I would expect this to work just the same in any level of the schema tree and not throw any errors.

@rndfm rndfm changed the title Schemas in separate project with arrays causes "Schema for array path someArrayPath is from a different copy of the Mongoose module." Schemas in separate project with arrays causes "Schema for array path is from a different copy of the Mongoose module." Apr 14, 2023
@vkarpov15 vkarpov15 added this to the 7.0.5 milestone Apr 19, 2023
@vkarpov15 vkarpov15 added the has repro script There is a repro script, the Mongoose devs need to confirm that it reproduces the issue label Apr 19, 2023
@IslandRhythms IslandRhythms added needs clarification This issue doesn't have enough information to be actionable. Close after 14 days of inactivity and removed has repro script There is a repro script, the Mongoose devs need to confirm that it reproduces the issue labels Apr 19, 2023
@IslandRhythms
Copy link
Collaborator

Since you've updated since you posted the issue, what error are you seeing, what command are you running?

@rndfm
Copy link
Author

rndfm commented Apr 20, 2023

Running the level1 and level2 apps in the demo repo should show the problem.
node level1app.js does not work. But it should.
node level2app.js works for me.

I updated the original issues and the demo repo to be more clear.

@IslandRhythms
Copy link
Collaborator

image
This is the error I get

@vkarpov15 vkarpov15 modified the milestones: 7.0.5, 7.1.1 Apr 21, 2023
@rndfm
Copy link
Author

rndfm commented Apr 23, 2023

image This is the error I get

What version of Node is that?
I just tried to clone the repo and run it with node version 18.13.0. And et runs fine. (Apart from the mongoose error)
image

I just added a very short readme

@rndfm
Copy link
Author

rndfm commented Apr 23, 2023

I tried to change the way i import mongoose types. Maybe this is more compatible?

Pull :)

@vkarpov15 vkarpov15 modified the milestones: 7.1.1, 7.1.2 Apr 27, 2023
@vkarpov15 vkarpov15 added has repro script There is a repro script, the Mongoose devs need to confirm that it reproduces the issue and removed needs clarification This issue doesn't have enough information to be actionable. Close after 14 days of inactivity labels May 11, 2023
@vkarpov15 vkarpov15 self-assigned this May 15, 2023
@vkarpov15 vkarpov15 modified the milestones: 7.1.2, 7.2.1 May 19, 2023
@vkarpov15
Copy link
Collaborator

The repro script you posted doesn't have a separate package for "shared", "shared" is a separate directory with Mongoose listed as a peerDependency. That setup won't work, "shared" isn't installed by npm so nothing will resolve its peer dependencies.

What's the output of npm list mongoose in your project?

@vkarpov15 vkarpov15 added needs clarification This issue doesn't have enough information to be actionable. Close after 14 days of inactivity and removed has repro script There is a repro script, the Mongoose devs need to confirm that it reproduces the issue labels May 23, 2023
@vkarpov15 vkarpov15 removed this from the 7.2.1 milestone May 23, 2023
@rndfm
Copy link
Author

rndfm commented May 24, 2023

All I'm trying to do is reuse some schemas across two or more projects. What would be the right way to do this?

@rndfm
Copy link
Author

rndfm commented May 24, 2023

And by the way. It works as expected when i comment out the line where the exception is thrown.

mongoose-schema-error\app\node_modules\mongoose\lib\schema.js:1277

@vkarpov15
Copy link
Collaborator

Depends on how your project is structured. In the setup in this repo: https://github.com/rndfm/mongoose-schema-error where you have multiple sibling directories, each with their own copy of Mongoose, I'd recommend either:

  1. Add a top-level node_modules directory and put Mongoose as a dependency there. That way both app and shared use the top-level mongoose package.
  2. Make shared only export the schema definition, not a Mongoose schema instance. So product.js exports { name: String } rather than new mongoose.Schema({ name: String }), company.js exports { products: [{ type: productSchemaDefinition }] } rather than { products: [productSchema] }. Export POJO, call new Schema() on that POJO.

The problems with multiple copies of the Mongoose modules are 1) incompatibilities between versions, and 2) any instanceof checks we use will break. So while your code may look like it works, we don't have tests in place to cover multi-module setups, so we're not as confident that Mongoose will work as designed in that case. That being said, we'll do some work to allow copying using new Schema() as the error message recommends.

vkarpov15 added a commit that referenced this issue May 25, 2023
@vkarpov15 vkarpov15 removed the needs clarification This issue doesn't have enough information to be actionable. Close after 14 days of inactivity label May 25, 2023
@vkarpov15 vkarpov15 modified the milestone: 7.2.1 May 25, 2023
@vkarpov15 vkarpov15 added this to the 7.2.2 milestone May 25, 2023
vkarpov15 added a commit that referenced this issue May 26, 2023
fix(schema): recursively copy schemas from different modules when calling `new Schema()`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants