kgrzybek/modular-monolith-with-ddd · warning · InvalidCommandException
{validator error messages}
Error message
{validator error messages} What it means
Thrown by the Payments module ValidationCommandHandlerWithResultDecorator, the TResult-returning counterpart of the validation decorator. It runs all FluentValidation validators for command T, aggregates the ErrorMessages, and throws InvalidCommandException(errors) when any validation fails. The placeholder '{validator error messages}' is replaced by the actual validator messages at throw time.
Source
Thrown at src/Modules/Payments/Infrastructure/Configuration/Processing/ValidationCommandHandlerWithResultDecorator.cs:32
public ValidationCommandHandlerWithResultDecorator(
IList<IValidator<T>> validators,
ICommandHandler<T, TResult> decorated)
{
this._validators = validators;
_decorated = decorated;
}
public Task<TResult> 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());
}
return _decorated.Handle(command, cancellationToken);
}
}
}View on GitHub (pinned to 91c8ef24b4)
Solutions
- Read ex.Errors to identify the failing validators and properties.
- Correct the command values to satisfy validation.
- Pre-validate on the client/API layer using the same validators.
- Adjust validator rules if a valid business value is being rejected.
Example fix
// before var id = await _commandDispatcher.SendAsync(new BuySubscriptionRenewalCommand(Guid.Empty, "", "", 0, "")); // after var id = await _commandDispatcher.SendAsync(new BuySubscriptionRenewalCommand(subscriptionId, "MONTHLY", "PL", 49.99m, "PLN"));
Defensive patterns
Strategy: validation
Validate before calling
var validator = new BuySubscriptionRenewalCommandValidator(); var result = await validator.ValidateAsync(cmd); if (!result.IsValid) return BadRequest(result.Errors.Select(e => e.ErrorMessage)); var id = await _commandDispatcher.SendAsync(cmd);
Try / catch
try { var id = await _commandDispatcher.SendAsync(cmd); }
catch (InvalidCommandException ex)
{ return BadRequest(new { errors = ex.Errors }); } Prevention
- Pre-validate result-returning commands with their validators client-side.
- Inspect ex.Errors for the offending properties.
- Ensure validators cover enum codes and money format.
When it happens
Trigger: Sending any Payments command that returns a result (e.g. BuySubscriptionRenewalCommand returns Guid) with properties that fail a registered validator.
Common situations: Same as the void decorator but on result-returning commands: missing required fields, invalid enum codes, malformed ids, bad money values.
Related errors
- {validator error messages}
- {validator error messages}
- {validator error messages}
- Command validation error
- Command validation error
AI-assisted analysis of kgrzybek/modular-monolith-with-ddd@91c8ef24b4 (2026-08-13).
Data as JSON: /api/errors/5b8067ef9d760912.
Report an issue: GitHub.