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

question: No metadata found. There is more than once class-validator version installed probably. You need to flatten your dependencies. #261

Closed
viktor-ku opened this issue Sep 20, 2018 · 65 comments · Fixed by #335
Labels
status: done/released Issue has been completed, no further action is needed. type: question Questions about the usage of the library.

Comments

@viktor-ku
Copy link

viktor-ku commented Sep 20, 2018

Hi. Can anyone describe what exactly is this?

I have like 4 of those messages

@DavidBabel
Copy link

Same issue for me, i don't exactly get why it prints

@NoNameProvided
Copy link
Member

Hi @viktor-ku and @DavidBabel!

What enviroment do you use class-validator? What other libraries do you use with it?

The reason to this error as the message states there are multiple class-validator versions in your node_modules folder and they do not share the same metadata storage. Let me explain in details below:

Reason

Why do I see this

First, historyically class-validator only checked the type of known properties when validating a class and this led to silent errors when no metadata was found for a class and class-validator validated nothing and stayed silent. So an option was added to throw an error on unknown classes and the above message is logged when that option is not enabled to warn you.

Technical reason

To understand the problem, first, we need to understand how class-validator knows what to check on the properties. It knows ther required types because of the attached decorators, which will register the expected type in an internal storage inside class-validator.

But that storage is not shared accross the different versions of class-validator, so if you declarad a semver range in your modules the way that they doesn't share the same allowed latest version then npm will install multiple versions for you and will break it.

So this is what propably is in your node_modules right now:

node_modules
  /class-validator@0.9.x
  /your-another-lib-or-something-else-using-class-validator (requires 0.8.x)
    /node_modules
	  /class-validator@0.8.x
  / ... lot of other folders
package.json (requires 0.9.x)

In the example above the module called your-another-lib-or-something-else-using-class-validator requires a different version of the class-validator than the main project, so npm will install that specific version for him, but that is our problem, because now if you want to validate any model defined in that module from the outside you will get the error because your outer proram will use class-validator@0.9.x while the inner program used the inner class-validator@0.9.y instance to register it's type metadata.

So the folder sturcutur we want is the following:

node_modules
  /class-validator@0.9.x
  /your-another-lib-or-something-else-using-class-validator (requires version 0.9.x)
  / ... lot of other folders
package.json (requires 0.9.x)

Solution

In short, you need to make sure to install the same class-validator accross all the projects you use together. This is most easily done by adding the same semver range, eg: 0.9.x. (You cannot use ^0.9.0 because we have not reached 1.0, so a minor change considered a major change by semver.)

Required extra steps

You need to update npm to the latest version, npm flatten the node_modules for you sice the 6. version only.

I hope I could explain the probem (this one is hard to explain!), if anything is not clear, feel free to ask more, and I will try my best to explain it.

@NoNameProvided NoNameProvided added status: awaiting answer Awaiting answer from the author of issue or PR. flag: needs docs labels Nov 4, 2018
@NoNameProvided
Copy link
Member

This is related to #132.

@NoNameProvided
Copy link
Member

An another explanation: #181 (comment)

@FSM1
Copy link

FSM1 commented Nov 8, 2018

@NoNameProvided I am also experiencing these errors and unable to validate. I have ensured that there is only one version of class-validator installed throughout my package tree. I have confirmed by searching the node_modules folder that only one version has been installed, and the node_modules has been flattened.

image

I still unfortunately get the error in my console and am unable to validate.

Thanks in advance.

@niekvb
Copy link

niekvb commented Nov 21, 2018

Faced the same problem, this helped for me:

Instead of declaring a variable with the type of the class

const user: User = {
    first: "John",
    last: "Doe",
};

Initialize the class first before assigning data

const user = User();
user.first = "John";
user.last = "Doe";

It might not be the most beautiful way to solve it, but it seems to work.

Let me know if this solves your issue.

@grbatinic-bogdan
Copy link

grbatinic-bogdan commented Nov 25, 2018

I'm having the same issue. In my project I have routing-controllers package which currently has outdated dependency of class-validator package. There's an open ticket for this as well.

I would argue that routing-controllers shouldn't have a hard dependency on class-validator package, because of the nature of this issue.

@diegolaciar
Copy link

diegolaciar commented Nov 29, 2018

@NoNameProvided,

I have the same issue, I get the warning and the validate don' t return any ValidationError.

I also I have confirmed by searching the node_modules folder that only one version has been installed, and the node_modules has been flattened.

npm v6.4.1

tried the command
npm dedupe
but no luck solving this issue.

thanks

@josephbuchma
Copy link

josephbuchma commented Dec 2, 2018

Having same issue, node_modules flattened 😞

@niekvb check out this

@josephbuchma
Copy link

Ok, I got it working! For some reason it does not work when used with typedi container.
To be more specific, it worked after I removed following piece:

// ...
import { Container } from 'typedi';
import * as ClassValidator from 'class-validator';

ClassValidator.useContainer(Container);

// ...

@RDeluxe
Copy link

RDeluxe commented Jan 15, 2019

Thanks, I had the same issue.
As we are using Lerna, the flattening is not an effective solution.
Let's say if have my own 2 packages, A and B, both having class-validator as a dependency.
Then, I add an external dependency, called C, to my B package. C also requires class-validator, but with another version.

Then, using lerna boostrap all the dependecies are installed in A/node_modules, B/node_modues, etc.
The last step lerna is taking, if you require local package in the same monorepo, is to create a symlink like A/node_modules/B -> ../../B. That's when you lose any flattened structure, and you end up with a different version of class-validator (as far as I can tell).

Setting the same version of class-validator used in C in my packages in both A and B solved the issue

@RDeluxe
Copy link

RDeluxe commented Feb 6, 2019

Hello again.

Seems that even with one single version of class-validator, the issue still exists. Any indications about why this could be the case ?

Edit:

Ok, after 2 hours trying to fix this, we realized that Typedi was not going to help (we did not manage to make it work).

Our use case is really simple: we use lerna. And as such, we don't have a flattened 'node_modules' during development.

class-validator should really support such a use case out of the box

@dreamdevil00
Copy link

@NoNameProvided

Hi, I reproduced the problem

Here is the bug repo link. It's a nestjs project using class-validator to validate inputs.

Bug condition:

  1. Run in debug mode
  2. There are path maps
  3. curl -X POST "http://localhost:3000/users" -H "accept: application/json" -H "Content-Type: application/json" -d "{ "username": "username", "password": "yourpassword", "firstName": "string", "lastName": "string", "address": "string"}"

The key point Code

thoughts?

@cdagli
Copy link

cdagli commented Feb 28, 2019

@RDeluxe for the Lerna case hoisting the related packages worked for us. Have you tried this?

Added the packages we want to hoist to the Lerna.json as below:

"hoist": [
        ....
        "class-validator",
        "reflect-metadata",
        ....
    ],

@Toxicable
Copy link

Im getting this error using the ValidationPipe from Nestjs.
With only 1 verssion of class-validator

$ npm ls class-validator
└── class-validator@0.9.1 

@nvuhung
Copy link

nvuhung commented Apr 20, 2019

Any update for this issue? I have same problem with only 1 version of class-validator:

$ npm ls class-validator
└── class-validator@0.9.1 

@cloakedch
Copy link

Same using NestJS (6.1.1):

$ npm ls class-validator
└── class-validator@0.9.1 

@vellengs
Copy link

Same issue, I found the problem is there are really have multiple modules inside the node_modules folder, but shows

$ npm ls class-validator
└── class-validator@0.9.1 

I currently use lerna to manage it, it seems copy the sub nodes_modules to the folder instead of flatten to install.

@vellengs
Copy link

vellengs commented Apr 23, 2019

Hello again.

Seems that even with one single version of class-validator, the issue still exists. Any indications about why this could be the case ?

Edit:

Ok, after 2 hours trying to fix this, we realized that Typedi was not going to help (we did not manage to make it work).

Our use case is really simple: we use lerna. And as such, we don't have a flattened 'node_modules' during development.

class-validator should really support such a use case out of the box

I think lerna caused problem with it.

@dima-gusyatiner
Copy link

dima-gusyatiner commented May 9, 2019

I spent a lot of time on this recently, and wanted to share my insights.
I made a little repository to reproduce the problem, check it out.

This issue is very inconvenient, to say the least.
I agree with @19majkel94, this solution from typeorm fits here and should be implemented as soon as possible.

TLDR: npm dedupe solves No metadata found. There is more than once class-validator version installed probably. You need to flatten your dependencies. So far, seems that there are no plans for a release that fixes this.

@neomedeiros
Copy link

neomedeiros commented May 13, 2019

Having the same message here, validation not working:

$ npm ls class-validator
└── class-validator@0.9.1

Trying to use sequelize instead of typeorm. Any thoughts?

@danloiterton
Copy link

danloiterton commented Jul 30, 2019

Hi, I have the same issue using a Lerna monorepo that includes a NestJS API and a custom module which both rely on class-validator. I tried removing the class-validator dependency from the NestJS API project, and instead exposing it from my module. When I publish and consume my custom module in the NestJS API, this seems to work.

HOWEVER, when I'm developing using lerna bootstrap (which symlinks the module to the api), I get the "No metadata found..." error and validation stops working. Under these circumstances, npm ls class-validator gives:

my-api@0.0.5 /myproject/packages/my-api
├─┬ my-module@0.0.5 -> /myproject/packages/my-module
│ └── class-validator@0.9.1 
└── class-validator@0.9.1  extraneous

Running lerna clean and then yarn install in my api package removes the symlink and once again uses the published version of my module. Now everything works again and npm ls class-validator gives:

my-api@0.0.5 /myproject/packages/my-api
└─┬ @my-module@0.0.5
  └── class-validator@0.9.1 

Obviously this is super-annoying as I can't develop my module and API in tandem. I haven't been able to get any of the above suggestions/workarounds to work yet. Anyone succeeded with the Lerna/NestJS/Custom module scenario?

@MichalLytek
Copy link
Contributor

@danloiterton Use deps hoisting.

@danloiterton
Copy link

@danloiterton Use deps hoisting.

Thanks for the response, @19majkel94. I had half-heartedly looked into this. I gave npm dedupe, and lerna bootstrap --hoist a go, but quickly got repulsed by error-log vomit all over the place.

With some more detailed research, trial and error, I now have it working!

For anyone else with this scenario, I ended up using yarn workspaces in conjunction with lerna.

This switch caused a whole bunch of "Duplicate identifier" errors during the typescript build process. These seemed to be caused by @types packages from the outer node_modules folder causing conflicts, despite node_modules being ignored in my tsconfig. Thanks to this stack overflow answer, I resolved these by adding the types:[] option to my tsconfig compilerOptions.

Hope that helps someone - it's been driving me nuts! o_O

@satanTime
Copy link
Contributor

aha, thanks.

Hi @rfgamaral, might you provide me a code sample that reproduces the issue?

@satanTime
Copy link
Contributor

I've created the env. Testing.

@satanTime
Copy link
Contributor

satanTime commented Mar 27, 2020

So, the problem is still within type-graphql because it uses class-validator as a dependency, but not as a peer dependency. Therefore it uses own stable version of class-validator. if you move rc version to the node_modules/type-graphql/node_modules/class-validator then it works correctly.
https://take.ms/8Y8sN

I think it makes sense to open a PR by moving class-validator to be in peerDependencies.

@rfgamaral
Copy link

@satanTime I've looked through type-graphql repository and there's a bunch of issues from the author stating the problem is on this package. Some of those even suggest to move class-validator to peer dependencies but they were closed as "won't fix".

Any chance you could go over there and create a new issue yourself? Maybe as a mantainer of this you'll have better luck?

Thank you for researching this.

@satanTime
Copy link
Contributor

I'm not a mantainer, I'm a contributor, we need to ask @vlapo.

Anyway I'll open a ticket and add references to other packages that use class-transformer as a peer dependency.

@satanTime
Copy link
Contributor

Added a comment here: MichalLytek/type-graphql#366

@rfgamaral
Copy link

I'm using Yarn so I've temporarily fixed like this:

"resolutions": {
  "class-validator": "0.12.0-rc.0"
}

@rfgamaral
Copy link

However, I'm not sure about one thing... I'm using @IsPositive() in a field and I get the error message "Argument Validation Error", but with v0.9.1 I get "Argument "first" must be a non-negative integer", feels more descriptive. Why the change in the error message to be less descriptive?

@jchapelle
Copy link

One easy way to get rid of this warning is to add one validation config somewhere in your code.
In one of my DTO, I just simply added the validation below and the warning message disappeared in my whole app. Cheers

... @IsOptional() @IsString() id?: string; ...

@rfgamaral
Copy link

@satanTime I just tested "class-validator": "0.12.0-rc.0" again against "type-graphql": "0.18.0-beta.15", which moved class-validator to a peer dependency and the problem still persists for me:

[1585680547852] INFO  (12061 on RICARDO): Server listening at http://127.0.0.1:3000
[1585680550589] INFO  (12061 on RICARDO): incoming request
    reqId: 1
    req: {
      "method": "POST",
      "url": "/api/graphql",
      "hostname": "localhost:3000",
      "remoteAddress": "127.0.0.1",
      "remotePort": 59726
    }
No metadata found. There is more than once class-validator version installed probably. You need to flatten your dependencies.
GET https://api.spacexdata.com/v3/launches (730ms)
[1585680551411] INFO  (12061 on RICARDO): request completed
    reqId: 1
    res: {
      "statusCode": 200
    }
    responseTime: 821.1755999997258

Thoughts?

@satanTime
Copy link
Contributor

Very interesting 🧠, could you share the code base with me?

@rfgamaral
Copy link

Very interesting 🧠, could you share the code base with me?

Added you as a collaborator to a private repo...

@satanTime
Copy link
Contributor

Hi @vlapo, I was able to reproduce the issue. I'll create PR with the fix soon, I'll try today but probably this week.

@satanTime
Copy link
Contributor

satanTime commented Mar 31, 2020

Okay, it was easy. (@rfgamaral you can delete me from the repo).

the error message comes from https://github.com/typestack/class-validator/blob/master/src/validation/ValidationExecutor.ts#L49
if you project doesn't use any decorator from class-validator then you'll get this error message anyway.

@rfgamaral, I would say , simply add validation rules to your model.

@vlapo, not sure if we should do anything here. If you have an idea - let me know, I'm always glad to contribute.
There's no big reason to log this error in console anymore. Only for old versions that can lose metadata when 2 versions of the lib are used.

@rfgamaral
Copy link

rfgamaral commented Mar 31, 2020

if you project doesn't use any decorator from class-validator then you'll get this error message anyway.

But I'm using @IsPositive() from class-validator...

@rfgamaral, I would say , simply add validation rules to your model.

I'm not sure what you mean, am I not doing that already with @IsPositive()?

@satanTime
Copy link
Contributor

@rfgamaral, I've not seen it in your repo. let's go back to the "chat" :)

@rfgamaral
Copy link

Sorry everyone, and sorry @satanTime for wasting your time. There was no problem, I made a bit mistake (kinda tired) and it was my problem all along.

Everything is great, please keep up the good work :)

@vlapo
Copy link
Contributor

vlapo commented Mar 31, 2020

I hate this misleading warn message but for now it is our only indication about missing metadata in prod (whatever it is because of no validation rules or more than one class-validator libs installed).
Lets to nothing now. We may change/remove this warn in the future

@vlapo
Copy link
Contributor

vlapo commented Mar 31, 2020

Thanks @satanTime for your quick reactions :)

@kctang
Copy link

kctang commented Apr 1, 2020

Hi guys, sharing my experience on this...stuck for 2-3 days, now I got a solution that words for my scenario.

I got the ~ error message when trying to validate models via Jest (unit test) in a NestJS project. The NestJS project references models from a Lerna monorepo (relative path - and NestJS is not part of the monorepo).

Jest references packages in the monorepo via moduleNameMapper like:

  "moduleNameMapper": {
    "^@my-lerna/(.*)$": "<rootDir>/../lib/packages/$1/src/index.ts"
  }

I think, the reason I am getting the error message is because the model files resolve 'class-validator' by traversing up its directory path. So, even when if i hoist dependencies to the root Lerna directory, it does not work.

Solution: Specifically, tell Jest know how to resolve 'class-validator' by adding an entry to moduleNameMapper (a Jest configuration option):

  "moduleNameMapper": {
    "class-validator": "<rootDir>/node_modules/class-validator",
    "^@my-lerna/(.*)$": "<rootDir>/../lib/packages/$1/src/index.ts"
  }

Hope this helps someone with similar scenario.

@ghost
Copy link

ghost commented Apr 5, 2020

Why the hell was this issue closed? It is still there...

@satanTime
Copy link
Contributor

Hello to your house too, @Syy0n.

Steps to reproduction please.

@glikaj
Copy link

glikaj commented Apr 8, 2020

For me it happens in authorizationChecker @satanTime.

const expressApp: Application = createExpressServer({
  //..
  authorizationChecker: async (action: Action, roles: string[]) => {
    const user = await connection.getMongoRepository(User).find();
    console.log(user);
    return true;
  },
  //...
}); 

This happens me when i call the User model or any other class that imports the 'class-validator'.

@satanTime
Copy link
Contributor

Hi @glikaj, the first thing is please verify you use 0.12.0-rc.0 and there's not any lib that uses another version. If the node_modules have only 0.12.0-rc.0 then it means there's no any validation rule and the case is similar to @rfgamaral had - just add a validation rule somewhere and the error should gone. Other cases I would say aren't possible, but I believe in magic and would like to ask you to share the source code for an investigation :)

@glikaj
Copy link

glikaj commented Apr 9, 2020

Thank you @satanTime, update to 0.12.0-rc.0 fixed the problem.

@lock
Copy link

lock bot commented Apr 17, 2020

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators Apr 17, 2020
@NoNameProvided NoNameProvided added status: done/released Issue has been completed, no further action is needed. and removed status: awaiting answer Awaiting answer from the author of issue or PR. labels Aug 8, 2020
@NoNameProvided NoNameProvided changed the title No metadata found. There is more than once class-validator version installed probably. You need to flatten your dependencies. question: No metadata found. There is more than once class-validator version installed probably. You need to flatten your dependencies. Aug 8, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
status: done/released Issue has been completed, no further action is needed. type: question Questions about the usage of the library.
Development

Successfully merging a pull request may close this issue.