Skip to content

@Min/@Max errors override @IsInt when value is NaN after transformation #2634

@NavidulHoque

Description

@NavidulHoque

When using class-transformer with class-validator in NestJS, and applying stopAtFirstError: true, the validation order can be unintuitive. Specifically, if a property is transformed into NaN (e.g., due to an undefined or missing value), the @min or @max decorators may throw an error before the @ISINT decorator, even though @ISINT is listed first.

Steps to Reproduce:

Define a DTO with @type(), @ISINT(), and @min() decorators:

import { Type } from 'class-transformer';
import { IsInt, Min } from 'class-validator';

export class PaginationDto {
@type(() => Number)
@ISINT({ message: 'Page must be an integer' })
@min(1, { message: 'Page must be at least 1' })
readonly page: number;
}

Send a request with an undefined or missing page property.

Apply stopAtFirstError: true in the ValidationPipe:

app.useGlobalPipes(
new ValidationPipe({
transform: true,
stopAtFirstError: true,
}),
);

Expected Behavior:

The validation should stop at the first error encountered. In this case, the first error should be from the @ISINT decorator, indicating that the value is not an integer.

Actual Behavior:

The validation stops at the @min decorator, which throws an error because NaN is not a valid number, overriding the @ISINT error.

Cause:

The @min and @max decorators internally call isNumber() from validator.js, which detects NaN and throws an error before the @ISINT decorator has a chance to validate.

Suggested Fix:

Ensure that the decorators respect the order in which they are applied and that stopAtFirstError functions as intended, stopping at the first decorator that fails validation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    status: needs triageIssues which needs to be reproduced to be verified report.type: fixIssues describing a broken feature.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions