← Dev log
EduQate·data integrity·2026-07-14

The same bug four times, three causes

Under NestJS ValidationPipe whitelist: true, a DTO property with no class-validator decorator is stripped from the payload silently — the same symptom from three different causes.

It said it worked

Green, 200, saved, “already handled” — and wrong. No error anywhere to go on.

First on program-fees, from the import type above. Then the identical symptom on document-requirements for a different reason: that DTO had no class-validator decorators at all, just plain declarations. A property with no decorator isn't recognized under whitelist: true, so the whole payload gets stripped.

Third time on form submission, where FormAnswer.value is a genuine union (string | string[] | number | boolean | null) because an answer's shape depends on the field type. Nobody had decorated it because no single @IsString()/@IsNumber() is correct for a union — which I hadn't known had an answer until then: @IsDefined() accepts any value and just requires the key.

After the second one I stopped fixing these one at a time and grepped for the pattern directly — DTO classes with declarations and no @Is-prefixed decorators. That caught application-requests.dto.ts before I burned a fourth cycle on it. When a root cause turns out to be an undocumented convention, sweep for it immediately instead of tripping over each instance.