NestJS ValidationPipe rejects request / metadata missing in CI
e2e tests fail with 400s because the global ValidationPipe rejected the payload. Either class-validator metadata is missing, or whitelist/forbidNonWhitelisted stripped or blocked fields the test sent.
What this error means
e2e requests that pass locally return "400 Bad Request" with a validation message array in CI, or every DTO passes with no validation because metadata was not emitted.
{
"statusCode": 400,
"message": ["email must be an email", "property extra should not exist"],
"error": "Bad Request"
}Common causes
forbidNonWhitelisted blocks unexpected fields
With whitelist and forbidNonWhitelisted, any property not in the DTO triggers a 400, so a test payload with extra keys fails.
class-validator metadata is not available
Without emitted decorator metadata or the polyfill, validators do not attach, so validation either misbehaves or silently passes.
How to fix it
Align the pipe options with the payload
- Decide whether extra fields should be stripped (whitelist) or rejected (forbidNonWhitelisted).
- Make test payloads match the DTO exactly under strict settings.
- Enable transform so incoming plain objects become DTO instances.
app.useGlobalPipes(new ValidationPipe({
whitelist: true,
forbidNonWhitelisted: true,
transform: true,
}));Ensure validator metadata is emitted
Keep emitDecoratorMetadata on and import reflect-metadata so class-validator decorators attach.
import 'reflect-metadata';How to prevent it
- Configure the global ValidationPipe once and test payloads against it.
- Keep decorator metadata enabled so validators attach.
- Cover validation rules with tests so behavior changes are caught.