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

Meeting comment for editing must exist.

Error message

Meeting comment for editing must exist.

What it means

Thrown by EditMeetingCommentCommandHandler when GetByIdAsync returns null for the MeetingCommentId. Editing requires an existing comment to load its commenting configuration and apply the change; a missing comment aborts with InvalidCommandException (HTTP 400).

Source

Thrown at src/Modules/Meetings/Application/MeetingComments/EditMeetingComment/EditMeetingCommentCommandHandler.cs:30

        private readonly IMeetingCommentingConfigurationRepository _meetingCommentingConfigurationRepository;
        private readonly IMemberContext _memberContext;

        internal EditMeetingCommentCommandHandler(
            IMeetingCommentRepository meetingCommentRepository,
            IMeetingCommentingConfigurationRepository meetingCommentingConfigurationRepository,
            IMemberContext memberContext)
        {
            _meetingCommentRepository = meetingCommentRepository;
            _meetingCommentingConfigurationRepository = meetingCommentingConfigurationRepository;
            _memberContext = memberContext;
        }

        public async Task Handle(EditMeetingCommentCommand command, CancellationToken cancellationToken)
        {
            var meetingComment = await _meetingCommentRepository.GetByIdAsync(new MeetingCommentId(command.MeetingCommentId));
            if (meetingComment == null)
            {
                throw new InvalidCommandException(["Meeting comment for editing must exist."]);
            }

            var meetingCommentingConfiguration = await _meetingCommentingConfigurationRepository.GetByMeetingIdAsync(meetingComment.GetMeetingId());

            meetingComment.Edit(_memberContext.MemberId, command.EditedComment, meetingCommentingConfiguration);
        }
    }
}

View on GitHub (pinned to 91c8ef24b4)

Solutions

  1. Confirm the comment still exists before offering the edit action.
  2. Pre-check existence in the controller and return 404.
  3. Disable the edit UI when the comment is no longer present.
  4. Map InvalidCommandException to 400/404 at the API boundary.

Example fix

// before
await _commandDispatcher.SendAsync(new EditMeetingCommentCommand(commentId, newText));

// after
var comment = await _meetingQueries.GetCommentAsync(commentId);
if (comment is null) return NotFound("Comment not found.");
await _commandDispatcher.SendAsync(new EditMeetingCommentCommand(commentId, newText));
Defensive patterns

Strategy: validation

Validate before calling

var comment = await _meetingQueries.GetCommentAsync(commentId);
if (comment is null) return NotFound("Comment not found.");
await _commandDispatcher.SendAsync(new EditMeetingCommentCommand(commentId, newText));

Type guard

public static bool IsValidEditCommand(EditMeetingCommentCommand c) =>
    c.MeetingCommentId != Guid.Empty && !string.IsNullOrWhiteSpace(c.EditedComment);

Try / catch

try { await _commandDispatcher.SendAsync(cmd); }
catch (InvalidCommandException ex) when (ex.Errors.Any(m => m.Contains("must exist")))
{ return NotFound(new { errors = ex.Errors }); }

Prevention

When it happens

Trigger: Dispatching EditMeetingCommentCommand for a comment id that does not exist or was removed: stale edit link, concurrent removal, wrong id.

Common situations: User opens an edit form for a comment that another flow deleted; client caches comment ids across sessions.

Related errors


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