{"record":{"id":"c863ff440c63614d","repo":"kgrzybek/modular-monolith-with-ddd","slug":"command-validation-error-c863ff","errorCode":null,"errorMessage":"Command validation error","messagePattern":"Command validation error","errorType":"validation","errorClass":"InvalidCommandException","httpStatus":400,"severity":"warning","filePath":"src/Modules/UserAccess/Infrastructure/Configuration/Processing/ValidationCommandHandlerWithResultDecorator.cs","lineNumber":33,"sourceCode":"        public ValidationCommandHandlerWithResultDecorator(\n            IList<IValidator<T>> validators,\n            ICommandHandler<T, TResult> decorated)\n        {\n            this._validators = validators;\n            _decorated = decorated;\n        }\n\n        public Task<TResult> Handle(T command, CancellationToken cancellationToken)\n        {\n            var errors = _validators\n                .Select(v => v.Validate(command))\n                .SelectMany(result => result.Errors)\n                .Where(error => error != null)\n                .ToList();\n\n            if (errors.Any())\n            {\n                throw new InvalidCommandException(errors.Select(x => x.ErrorMessage).ToList());\n            }\n\n            return _decorated.Handle(command, cancellationToken);\n        }\n    }\n}","sourceCodeStart":15,"sourceCodeEnd":39,"githubUrl":"https://github.com/kgrzybek/modular-monolith-with-ddd/blob/91c8ef24b4cb6ef558c95d8267fa07d68c7059f8/src/Modules/UserAccess/Infrastructure/Configuration/Processing/ValidationCommandHandlerWithResultDecorator.cs#L15-L39","documentation":"Thrown by the UserAccess module ValidationCommandHandlerWithResultDecorator (TResult-returning variant). It runs all FluentValidation validators for command T, aggregates ErrorMessages, and throws InvalidCommandException(errors) with the literal message 'Command validation error'; the actionable detail is in Errors.","triggerScenarios":"Sending a result-returning UserAccess command (e.g. authenticate, register user) with properties failing a registered validator.","commonSituations":"Authentication/register commands with empty login, weak password, or missing required fields.","solutions":["Read ex.Errors for the specific failing validators (message is generic).","Fix the command values to pass validation.","Pre-validate on the client with the same rules.","Adjust validators if a valid value is wrongly rejected."],"exampleFix":"// before\nvar userId = await _commandDispatcher.SendAsync(new AuthenticateCommand(\"\", \"\"));\n\n// after\nvar userId = await _commandDispatcher.SendAsync(new AuthenticateCommand(login, password));","handlingStrategy":"validation","validationCode":"var validator = new AuthenticateCommandValidator();\nvar result = await validator.ValidateAsync(cmd);\nif (!result.IsValid) return BadRequest(result.Errors.Select(e => e.ErrorMessage));\nvar userId = await _commandDispatcher.SendAsync(cmd);","typeGuard":null,"tryCatchPattern":"try { var userId = await _commandDispatcher.SendAsync(cmd); }\ncatch (InvalidCommandException ex)\n{ return BadRequest(new { errors = ex.Errors }); } // message is generic; detail is in Errors","preventionTips":["Validate required credentials client-side before dispatch.","Always read ex.Errors since the summary message is generic.","Keep validators current with command DTO changes."],"tags":["user-access","validation","fluentvalidation","command-handler","invalid-command-exception","decorator"],"backgroundTag":null,"analyzedSha":"91c8ef24b4cb6ef558c95d8267fa07d68c7059f8","analyzedAt":"2026-08-13T17:18:16.571Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}