{"record":{"id":"47347fcd379f0057","repo":"fullstackhero/dotnet-starter-kit","slug":"validationexception-failures","errorCode":null,"errorMessage":"ValidationException(failures)","messagePattern":"ValidationException\\(failures\\)","errorType":"validation","errorClass":"FluentValidation.ValidationException","httpStatus":400,"severity":"warning","filePath":"src/BuildingBlocks/Web/Mediator/Behaviors/ValidationBehavior.cs","lineNumber":42,"sourceCode":"\n        if (_validators.Length > 0)\n        {\n            var context = new ValidationContext<TMessage>(message);\n            List<ValidationFailure> failures;\n\n            if (_validators.Length == 1)\n            {\n                var result = await _validators[0].ValidateAsync(context, cancellationToken).ConfigureAwait(false);\n                failures = result.Errors;\n            }\n            else\n            {\n                var results = await Task.WhenAll(_validators.Select(v => v.ValidateAsync(context, cancellationToken))).ConfigureAwait(false);\n                failures = results.SelectMany(r => r.Errors).ToList();\n            }\n\n            if (failures.Count > 0)\n                throw new ValidationException(failures);\n        }\n\n        return await next(message, cancellationToken).ConfigureAwait(false);\n    }\n}","sourceCodeStart":24,"sourceCodeEnd":47,"githubUrl":"https://github.com/fullstackhero/dotnet-starter-kit/blob/3f2959e683e9f83f13e55e1678c9119f63c7e8e5/src/BuildingBlocks/Web/Mediator/Behaviors/ValidationBehavior.cs#L24-L47","documentation":"ValidationBehavior is a Mediator pipeline behavior that runs all registered FluentValidation validators for an incoming command/query. If any validation errors are collected, it throws ValidationException(failures) and the handler never executes. The exception carries the full list of property-level failures.","triggerScenarios":"Dispatching any command/query whose input violates an {Name}Validator rule (empty required strings, out-of-range numbers, invalid format), causing failures.Count > 0 in ValidationBehavior.Handle.","commonSituations":"Frontend sending empty payloads; missing required fields when calling API endpoints directly (Postman/OpenAPI); new validator rules added that break existing callers; null DTO fields from deserialization.","solutions":["Inspect ValidationException.Errors to see which properties failed and why, then fix the request payload.","Validate input client-side (e.g. zod + react-hook-form) mirroring server rules.","Register a behavior/middleware that maps ValidationException to a 400 ProblemDetails response.","Update the corresponding {Name}Validator if a rule is wrong or newly added and breaks legit callers."],"exampleFix":"// before: dispatching unvalidated input\nawait mediator.Send(new CreateProductCommand(\"\"));\n\n// after: check validation result shape\ntry {\n    await mediator.Send(new CreateProductCommand(dto.Name));\n} catch (ValidationException vex) {\n    var problems = vex.Errors.GroupBy(e => e.PropertyName)\n        .ToDictionary(g => g.Key, g => g.Select(e => e.ErrorMessage).ToArray());\n    return Results.ValidationProblem(problems);\n}","handlingStrategy":"try-catch","validationCode":"// client-side mirror of the server validator (zod example)\nconst schema = z.object({ name: z.string().min(1, 'Name is required') });\nschema.parse(command); // throws before the request is sent","typeGuard":"bool IsValid<T>(T message, IEnumerable<IValidator<T>> validators) =>\n    validators.All(v => v.Validate(new ValidationContext<T>(message)).IsValid);","tryCatchPattern":"try {\n    await mediator.Send(command);\n} catch (ValidationException vex) {\n    var errors = vex.Errors.GroupBy(e => e.PropertyName)\n        .ToDictionary(g => g.Key, g => g.Select(e => e.ErrorMessage).ToArray());\n    return Results.ValidationProblem(errors); // 400\n}","preventionTips":["Validate forms in the UI (react-hook-form + zod) matching server rules.","Always register a {Name}Validator for new commands/queries — the architecture tests enforce it.","When a validator changes, search for all callers and update payloads."],"tags":["validation","fluentvalidation","cqrs","mediator"],"backgroundTag":"schema-validation-failed","analyzedSha":"3f2959e683e9f83f13e55e1678c9119f63c7e8e5","analyzedAt":"2026-09-15T22:20:53.684Z","contentChangedAt":"2026-09-15T22:20:53.684Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}