fullstackhero/dotnet-starter-kit · error · ArgumentException
ChannelId is required.
Error message
ChannelId is required.
What it means
Message.Create validates that a message is always attached to a channel: a Guid.Empty channelId fails ArgumentException with the parameter name. Since Guid is a value type, null is impossible — 'unset' is represented as Guid.Empty and explicitly rejected. This is a missing-required-argument guard at the domain factory.
Solutions
- Pass a valid non-empty channel id loaded from an existing ChatChannel (channel.Id) into Message.Create.
- Guard earlier in the pipeline: FluentValidation RuleFor(x => x.ChannelId).NotEmpty() on the command so it never reaches the domain.
- Fix 'new Guid()' usages / missing mapping that produce Guid.Empty.
- If channelId comes from a route/body, return 400 at the binding/validation layer with a clear message.
Example fix
// before
var message = Message.Create(Guid.Empty, authorUserId, body);
// after
RuleFor(x => x.ChannelId).NotEmpty();
...
var channel = await db.Channels.FindAsync([command.ChannelId], ct)
?? throw new NotFoundException(nameof(ChatChannel), command.ChannelId);
var message = Message.Create(channel.Id, command.AuthorUserId, command.Body); Defensive patterns
Strategy: validation
Validate before calling
public static bool HasChannelId(Guid channelId) => channelId != Guid.Empty;
Type guard
if (command.ChannelId == Guid.Empty) throw new ValidationException("ChannelId is required."); Try / catch
try { var m = Message.Create(channelId, authorId, body); } catch (ArgumentException ex) when (ex.ParamName == "channelId") { throw new ValidationException("ChannelId is required."); } Prevention
- Add RuleFor(x => x.ChannelId).NotEmpty() to the command validator
- Avoid new Guid(); assign ids at construction time
- Verify mapping of channelId from route/body into the command
- Resolve the channel entity and use its Id when creating messages
When it happens
Trigger: Calling Message.Create(channelId: Guid.Empty, ...) — typically an uninitialized Guid field/property, a record deserialized from a payload where channelId was missing/default, or a handler that never assigned the route/channel parameter.
Common situations: new Guid() instead of Guid.NewGuid(); request DTO with missing channelId defaulting to Guid.Empty; mapping bugs where the channel id is copied from the wrong source; tests constructing messages without an id.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Group DM requires at least 3 distinct members.
- Cannot start a DM with yourself.
- All user ids must be non-empty.
- Only named Channels can be renamed.
- Only named Channels can change privacy.
AI-assisted analysis of fullstackhero/dotnet-starter-kit@3f2959e683 (2026-09-15).
Data as JSON: /api/errors/4f388a5b57cca3b9.
Report an issue: GitHub.
Appendix: source
Thrown at src/Modules/Chat/Modules.Chat/Domain/Message.cs:45
private readonly List<MessageMention> _mentions = [];
public IReadOnlyList<MessageMention> Mentions => _mentions;
private readonly List<MessageReaction> _reactions = [];
public IReadOnlyList<MessageReaction> Reactions => _reactions;
private Message() { }
public static Message Create(
Guid channelId,
string authorUserId,
string? body,
Guid? parentMessageId = null,
IReadOnlyList<ParsedMention>? mentions = null)
{
ArgumentException.ThrowIfNullOrWhiteSpace(authorUserId);
if (channelId == Guid.Empty)
{
throw new ArgumentException("ChannelId is required.", nameof(channelId));
}
// Body is optional here; the SendMessage validator enforces "body OR >=1 attachment"
// (attachments attach AFTER Create via AddAttachment).
var trimmed = string.IsNullOrWhiteSpace(body) ? null : body.Trim();
var m = new Message
{
Id = Guid.CreateVersion7(),
ChannelId = channelId,
AuthorUserId = authorUserId,
Body = trimmed,
ParentMessageId = parentMessageId,
CreatedAtUtc = DateTime.UtcNow,
};
if (mentions is not null)
{
foreach (var pm in mentions)View on GitHub (pinned to 3f2959e683)