kgrzybek/modular-monolith-with-ddd · warning · InvalidCommandException

{validator error messages}

Error message

{validator error messages}

What it means

Thrown by the Registrations module ValidationCommandHandlerDecorator. It wraps every Registrations command handler, runs all FluentValidation validators for command T, collects ErrorMessages, and throws InvalidCommandException(errors) on any failure. The '{validator error messages}' placeholder resolves to the actual validator messages.

Source

Thrown at src/Modules/Registrations/Infrastructure/Configuration/Processing/ValidationCommandHandlerDecorator.cs:32

        public ValidationCommandHandlerDecorator(
            IList<IValidator<T>> validators,
            ICommandHandler<T> decorated)
        {
            this._validators = validators;
            _decorated = decorated;
        }

        public async Task Handle(T command, CancellationToken cancellationToken)
        {
            var errors = _validators
                .Select(v => v.Validate(command))
                .SelectMany(result => result.Errors)
                .Where(error => error != null)
                .ToList();

            if (errors.Any())
            {
                throw new InvalidCommandException(errors.Select(x => x.ErrorMessage).ToList());
            }

            await _decorated.Handle(command, cancellationToken);
        }
    }
}

View on GitHub (pinned to 91c8ef24b4)

Solutions

  1. Inspect ex.Errors for the failing validators and properties.
  2. Correct the command values (valid email, password policy, required ids).
  3. Mirror validators on the client to fail fast.
  4. Update validators if a legitimate value is rejected.

Example fix

// before
await _commandDispatcher.SendAsync(new RegisterNewUserCommand("", "weak", ""));

// after
await _commandDispatcher.SendAsync(new RegisterNewUserCommand("user@example.com", "StrongP@ss1!", "user"));
Defensive patterns

Strategy: validation

Validate before calling

var validator = new RegisterNewUserCommandValidator();
var result = await validator.ValidateAsync(cmd);
if (!result.IsValid) return BadRequest(result.Errors.Select(e => e.ErrorMessage));
await _commandDispatcher.SendAsync(cmd);

Try / catch

try { await _commandDispatcher.SendAsync(cmd); }
catch (InvalidCommandException ex)
{ return BadRequest(new { errors = ex.Errors }); }

Prevention

When it happens

Trigger: Sending a Registrations command (e.g. register member, confirm registration) with properties failing a registered validator: empty login/email, password below policy, missing meeting group id, invalid invite token.

Common situations: Public registration form submits an invalid email/weak password; admin invites with a blank email; test omits required registration fields.

Related errors


AI-assisted analysis of kgrzybek/modular-monolith-with-ddd@91c8ef24b4 (2026-08-13). Data as JSON: /api/errors/499c4970541246b4. Report an issue: GitHub.