Nest: ValidationPipe not working

Created on 25 Jan 2018  ·  14Comments  ·  Source: nestjs/nest

I'm submitting a...


[ ] Regression 
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

To be quite concise: the ValidationPipe doesn't work at all. Maybe I'm not using the way it is intended to be used but that seems unlikely.
It looks like no validation is performed at all.

Expected behavior

I expect to get a validation error thrown at my face.

Minimal reproduction of the problem with instructions

Here is a repository which provides all information to reproduce my issue: https://github.com/fwoelffel/nestjs-validation-bug

Clone, install and start the NestJS application:

git clone https://github.com/fwoelffel/nestjs-validation-bug.git
cd nestjs-validation-bug
npm install
npm start

Now, the http://localhost:3000 endpoint expects a POST request containing a payload of type MyDto.
Here is the DTO definition:

import { IsNumber } from 'class-validator';

export class MyDto {
  @IsNumber()
  readonly test: number;
}

And here is the controller:

import { Controller, Post, Body, ValidationPipe } from '@nestjs/common';
import { MyDto } from "./my.dto";

@Controller()
export class AppController {
  @Post()
  root(@Body(new ValidationPipe()) data: MyDto) {
    return data.test;
  }
}

Finally, here is the cURL command to perform a request with an invalid payload (according to my DTO definition):

curl -v \
  http://localhost:3000/ \
  -H 'cache-control: no-cache' \
  -H 'content-type: application/json' \
  -d '{
    "test": "I AM NOT A NUMBER! PLEASE TRIGGER A VALIDATION ERROR"
}'

As you can see, here is what the controller responds:

*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 3000 (#0)
> POST / HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.47.0
> Accept: */*
> cache-control: no-cache
> content-type: application/json
> Content-Length: 66
> 
* upload completely sent off: 66 out of 66 bytes
< HTTP/1.1 201 Created
< X-Powered-By: Express
< Content-Type: text/html; charset=utf-8
< Content-Length: 52
< ETag: W/"34-dEFIJF4e8ZgnTeWs0topCHUb1WY"
< Date: Thu, 25 Jan 2018 17:51:12 GMT
< Connection: keep-alive
< 
* Connection #0 to host localhost left intact
I AM NOT A NUMBER! PLEASE TRIGGER A VALIDATION ERROR% 

The expected output was obviously a validation error response.

Environment


Nest version: 4.5.10


For Tooling issues:
- Node version: v8.9.4
- Platform:  Linux

Most helpful comment

I've been hitting my head for some hours for this issue. I've found out it is about the version mismatch of class-validator versions between the project and nest.

For example: If you have a recent class-validator version (as 0.8.1) and use a recent @nest/common version (like 4.5.9, that will pull itself a class-validator version of 0.7.3), your Pipe won't work: your dtos are in version 8.x and the pipe will use version 7.x and there is a failure on that.

I don't believe its an API error from class-validator, but something internally changed to make the versions non-compatible. If you leave the SAME code but solve the version mismatch, everything works.

Now, solution time: what can be done?
1) Use latest version and wait for PR #383 to land. Slowly but readily the version matches.
2) Downgrade your version in package.json
3) Copy and Paste the TransformPipe inside your project. You only have to fix the imports, but without changing the implementation, it will work since its using also your project version.

I've tested myself the options 2 and 3 (so I'm not just theorizing), and will actually proceed with option 3: I'll get latest versions and will leave all working even after the PR lands (and can then update). Option 1 doesnt work before PR and Option 2 will make this issue reappear after the PR.

My 2 cents :)

All 14 comments

I had the same problem, I resolved this by removing node_modules directory. Now i have @nestjs/common in version 4.5.9 and class-validator in 0.7.3. I had class-validator in 0.8.

Yup, I came to the same conclusion that it has something to do with class-validator. Maybe we can close this issue?

Is this bug from class-validator? Or caused by some breaking changes?

Looks like class-validator has breaking changes https://github.com/typestack/class-validator/blob/master/CHANGELOG.md 😞

This PR (https://github.com/nestjs/nest/pull/383) would fix this since the class-validator dependency gets updated (btw, the guy who submitted this is really awesome :wink: )

I've been hitting my head for some hours for this issue. I've found out it is about the version mismatch of class-validator versions between the project and nest.

For example: If you have a recent class-validator version (as 0.8.1) and use a recent @nest/common version (like 4.5.9, that will pull itself a class-validator version of 0.7.3), your Pipe won't work: your dtos are in version 8.x and the pipe will use version 7.x and there is a failure on that.

I don't believe its an API error from class-validator, but something internally changed to make the versions non-compatible. If you leave the SAME code but solve the version mismatch, everything works.

Now, solution time: what can be done?
1) Use latest version and wait for PR #383 to land. Slowly but readily the version matches.
2) Downgrade your version in package.json
3) Copy and Paste the TransformPipe inside your project. You only have to fix the imports, but without changing the implementation, it will work since its using also your project version.

I've tested myself the options 2 and 3 (so I'm not just theorizing), and will actually proceed with option 3: I'll get latest versions and will leave all working even after the PR lands (and can then update). Option 1 doesnt work before PR and Option 2 will make this issue reappear after the PR.

My 2 cents :)

Hi,
Thanks @ShadowManu for a deep explanation. Since it's something related to the class-validator, the only thing that we can do from nest perspective is to update packages. I'll take a look into #383 PR very quick and probably merge as soon as possible 🙂

So I have actually the exact same issue with v4.6.6 using [email protected]. Should this issue be fixed with those versions?

@Get("/api/documents")
public async documents(@Query(new ValidationPipe({transform: true})) pagination: Pagination, @Res() response: Response);

export class Pagination {
    @IsInt()
    @IsPositive()
    @IsOptional()
    @ApiModelProperty()
    readonly limit: number;
}

The ValidationPipe is happy with non-numbers in limit tho and gives me Pagination {limit: 'NOT A NUMBER!!' }

Also, maybe another issue, but the Swagger module says my route has no parameters. Weird.

Ok, got the validation working, I had in app/node_modules/@nestjs/common/node_modules a class-validator, although I use in mine Dtos the class-validator of app/node_modules/class-validator. Maybe you should put 'class-validator' in peerDependencies or tell people in the docs that they have to remove nestjs/common's class-validator package when you add class-validator manually after installing nestjs/common.

At least it throws now an exception:
screen shot 2018-03-19 at 03 08 28

Now, I need to figure out how to automatically convert numeric-strings into a number. 🤷‍♂️

What chanlito says. Your validator is now properly working but the data you're validating is not: limit incoming as string before the numeric validation. So the validator is properly saying it's wrong.

EDIT: consider either convert before (as you said) or use another validation (like IsNumberString)

Cool, thank you guys, works now :) Any idea how I can get all the information into my Swagger UI using this ValidationPipe? At my route from above the Swagger UI says "No parameters". Is it correct, that I have to use @ApiImplicityQuery when I want to have my query DTO documented in nestjs/swagger module and ValidatorPipe does not help me here?

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.

Was this page helpful?
0 / 5 - 0 ratings