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

Validation fails with latest 0.14.0 version of class-validator #10683

Closed
5 of 15 tasks
NoNameProvided opened this issue Dec 9, 2022 · 15 comments
Closed
5 of 15 tasks

Validation fails with latest 0.14.0 version of class-validator #10683

NoNameProvided opened this issue Dec 9, 2022 · 15 comments

Comments

@NoNameProvided
Copy link

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

Note
This is an issue opened by a class-validatior maintainer to raise awareness of the latest breaking change in the class-validator@0.14.0 version and provide guidance on how to work around it.

The latest 0.14.0 release of class-validator changed the default option for forbidUnknownValues from false to true. The old behavior can be restored by specifying forbidUnknownValues: false when providing ValidatorOptions to NestJS.

This means validation of class instances where no actual validation takes place will fail instead of silently passing. This is the expected behavior for the majority of use cases.

There are two scenarios when this can happen:

  • the metadata is not registered correctly
  • when using group validation and the specified validation group results in zero validation applied

The first case will be a misconfiguration in your project 99% of the time, and you probably never want to allow payloads to bypass validation due to missing metadata. In this case, you need to find out why no metadata is present to do validations.

The second case may be a legit use case when you want to support validation groups that are exclusive to each other. If the called validation excludes all metadata due to the specified group then the validation will fail from now on instead of passing. Example:

class MyPayload {
    @IsString({ groups: ['A']})
    property: string;

    constructor(property: string) {
      this.property = property;
    }
}

validate(new MyPayload('value'), { groups: ['B'] }).then(console.log);

Calling the above will result in an error from now on:

[
  ValidationError {
    target: MyPayload { property: 'value' },
    value: undefined,
    property: undefined,
    children: [],
    constraints: {
      unknownValue: 'an unknown value was passed to the validate function'
    }
  }
]

If this is your use case you need to restore forbidUnknownValues: false or re-think your approach to how you are using groups.

For more details see PR #1798 and #1422 (comment).

Minimum reproduction code

https://github.com/typestack/class-validator/blob/develop/CHANGELOG.md#0140-2022-12-09

Steps to reproduce

  1. update class-validator to the latest 0.14.0 version
  2. use group validation or incorrectly configure your decorator metadata
  3. observe the failing validations which were passing in the previous versions

Expected behavior

The affected code is updated by the affected developers.

Package

  • I don't know. Or some 3rd-party package
  • @nestjs/common
  • @nestjs/core
  • @nestjs/microservices
  • @nestjs/platform-express
  • @nestjs/platform-fastify
  • @nestjs/platform-socket.io
  • @nestjs/platform-ws
  • @nestjs/testing
  • @nestjs/websockets
  • Other (see below)

Other package

class-validator

NestJS version

9.2.1

Packages versions

Node.js version

v18.12.1

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

No response

@NoNameProvided NoNameProvided added the needs triage This issue has not been looked into label Dec 9, 2022
@NoNameProvided
Copy link
Author

This issue may be pinned for the next few days.

@batflarrow
Copy link

batflarrow commented Dec 12, 2022

There are two scenarios when this can happen:

the metadata is not registered correctly

@NoNameProvided It would be helpful if you could provide a few examples of this case where you say metadata is not registered correctly.
If I am upgrading the package, then just checking if at least some decorators are added to the classes which are being used for validation would do the job, or do I need to check for something else as well?

@micalevisk
Copy link
Member

@NoNameProvided
Copy link
Author

It would be helpful if you could provide a few examples of this case where you say metadata is not registered correctly.

If in the previous version you saw validation errors, then 99% chance that your setup works correctly.

A possible scenario is when you use a different package to define the payload classes used for validation and you use inconsistent class-validator versions between that package and your main project. In that case, your node_modules may end up like this:

node_modules
  /your-shared-package
    /node_modules
      /class-validator@x
  /class-validator@y

In this setup, the decorators on your classes register the metadata in version x but your application asks version y to do the validation.

This may lead to situations when validation is silently passed without any actual validation taking place.

@NoNameProvided
Copy link
Author

@micalevisk I am not sure what reproduction case do you asking for. This is an issue opened to raise awareness of a breaking change. I myself did not run into any problems with NestJs so I have no reproduction case to provide.

@mschnee
Copy link

mschnee commented Dec 13, 2022

Example:

/**
 * This post body is completely undecorated.
 */
class MyInputModel {
  foo: string;
}

@Controller('/test')
export class MyTestController {
  @Post()
  async postTest(@Body() body: MyInputModel) {
    return; // expect HTTP 201, receive HTTP 400
  }
}

Suggestions for developers running into this error:

  • Pin to class-validator < 0.14
  • Use the option {forbidUnknownValues: false}, e.g. app.useGlobalPipes(new ValidationPipe({forbidUnknownValues: false}));
  • Update models to include class-validator decorators.

The following documentation may need to be updated:

Since TypeScript does not store metadata about generics or interfaces, when you use them in your DTOs, ValidationPipe may not be able to properly validate incoming data. For this reason, consider using concrete classes in your DTOs.

@mikeilabs
Copy link

When using @param it fails even when setting the forbidUnknownValues to false and even if you use no pipes.
example:
@param('someParam'): any

@Clashsoft
Copy link

See GHSA-fj58-h2fr-3pp2. This should be fixed ASAP

@scopsy
Copy link

scopsy commented Jan 13, 2023

@NoNameProvided any tips on the the metadata is not registered correctly we have a monorepo (novuhq/novu#2494) and I've updated typescript versions to match on relevant packages, but seems like still it's failing in this scenario.

Any tips?

@jtimmons
Copy link
Contributor

@scopsy my team ran into a similar issue in our monorepo - we ended up tracking it down to what we think is an issue in class-transformer that I just opened typestack/class-transformer#1440 to address. FYI @NoNameProvided

typestack/class-transformer#1043 gives a really good description of the problem with sharing validators within a monorepo. We ended up using a very similar workaround as the people from that thread:

  1. Making class-validator and class-transformer peer dependencies in our shared libraries to remove additional installations of those packages - this fixes things for published packages
  2. Using tsconfig compiler paths to force the server to only use its local reference (same concept as this workaround but without webpack) - this fixes things for local development

@jameskentTX
Copy link

Npm is showing errors when class-validator is updated from 0.13.2 to 0.14.0

Could not resolve dependency:
npm ERR! peerOptional class-validator@"^0.11.1 || ^0.12.0 || ^0.13.0" from @nestjs/mapped-types@1.2.0
npm ERR! node_modules/@nestjs/mapped-types
npm ERR! @nestjs/mapped-types@"^1.1.0" from the root project

@Kawacrepe
Copy link

Npm is showing errors when class-validator is updated from 0.13.2 to 0.14.0

Could not resolve dependency: npm ERR! peerOptional class-validator@"^0.11.1 || ^0.12.0 || ^0.13.0" from @nestjs/mapped-types@1.2.0 npm ERR! node_modules/@nestjs/mapped-types npm ERR! @nestjs/mapped-types@"^1.1.0" from the root project

See this comment from jmcdo nestjs/mapped-types#949 (comment)

@kamilmysliwiec
Copy link
Member

Since this caused quite an important regression (described here #10683 (comment)) I'm going to create a PR shortly that will set forbidUnknownValues to false by default. We can think about removing this fallback in the next major release

@Flusinerd
Copy link
Contributor

That sounds like a good solution.
Maybe we can display some kind of warning for a while when no value is provided for forbidUnknownValues just so developers will be aware of an upcoming breaking change?

@Mingyang-Li
Copy link

I've having the same issue with class-validator as well, but using TypeGraphQL. There's no options to do app.useGlobalPipes(new ValidationPipe({forbidUnknownValues: false})); like how nestjs does it, does anyone happen to know a TypeGraphQL equivalent version of this fix?

TIA

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests