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

  1. Pass a valid non-empty channel id loaded from an existing ChatChannel (channel.Id) into Message.Create.
  2. Guard earlier in the pipeline: FluentValidation RuleFor(x => x.ChannelId).NotEmpty() on the command so it never reaches the domain.
  3. Fix 'new Guid()' usages / missing mapping that produce Guid.Empty.
  4. 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

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


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)