kgrzybek/modular-monolith-with-ddd · error · InvalidCommandException
To add like the comment must exist.
Error message
To add like the comment must exist.
What it means
Thrown by AddMeetingCommentLikeCommandHandler when _meetingCommentRepository.GetByIdAsync returns null for the supplied MeetingCommentId. A like must attach to an existing comment, so a missing comment aborts the command with InvalidCommandException (HTTP 400).
Source
Thrown at src/Modules/Meetings/Application/MeetingComments/AddMeetingCommentLike/AddMeetingCommentLikeCommandHandler.cs:35
public AddMeetingCommentLikeCommandHandler(
IMeetingCommentRepository meetingCommentRepository,
IMeetingMemberCommentLikesRepository meetingMemberCommentLikesRepository,
IMemberContext memberContext,
ISqlConnectionFactory sqlConnectionFactory)
{
_meetingCommentRepository = meetingCommentRepository;
_memberContext = memberContext;
_sqlConnectionFactory = sqlConnectionFactory;
_meetingMemberCommentLikesRepository = meetingMemberCommentLikesRepository;
}
public async Task Handle(AddMeetingCommentLikeCommand request, CancellationToken cancellationToken)
{
var meetingComment = await _meetingCommentRepository.GetByIdAsync(new MeetingCommentId(request.MeetingCommentId));
if (meetingComment == null)
{
throw new InvalidCommandException(["To add like the comment must exist."]);
}
var connection = _sqlConnectionFactory.GetOpenConnection();
var likerMeetingGroupMemberData = await MembersQueryHelper.GetMeetingGroupMember(_memberContext.MemberId, meetingComment.GetMeetingId(), connection);
var meetingMemeberCommentLikesCount = await _meetingMemberCommentLikesRepository.CountMemberCommentLikesAsync(
_memberContext.MemberId,
new MeetingCommentId(request.MeetingCommentId));
var like = meetingComment.Like(_memberContext.MemberId, likerMeetingGroupMemberData, meetingMemeberCommentLikesCount);
await _meetingMemberCommentLikesRepository.AddAsync(like);
}
}
}View on GitHub (pinned to 91c8ef24b4)
Solutions
- Confirm the MeetingCommentId refers to an existing, non-removed comment.
- Ensure the client sends the comment id, not the meeting or reply id.
- Pre-check comment existence in the controller and return 404.
- Map InvalidCommandException to a 400/404 at the API boundary.
Example fix
// before
await _commandDispatcher.SendAsync(new AddMeetingCommentLikeCommand(commentId));
// after
var comment = await _meetingQueries.GetCommentAsync(commentId);
if (comment is null) return NotFound("Comment not found.");
await _commandDispatcher.SendAsync(new AddMeetingCommentLikeCommand(commentId)); 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 AddMeetingCommentLikeCommand(commentId)); Type guard
public static bool IsValidCommentId(AddMeetingCommentLikeCommand c) =>
c.MeetingCommentId != Guid.Empty; 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
- Pass the comment id, never the meeting id, when liking.
- Hide the like control once a comment is reported removed.
- Guard against double-like dispatch (also avoids duplicate-like business rule).
When it happens
Trigger: Dispatching AddMeetingCommentLikeCommand for a comment id that does not exist: wrong Guid, comment was removed, reply-vs-comment id confusion, or a stale client reference.
Common situations: User likes a comment that was just deleted by its author; race between render and like; client passes the meeting id instead of the comment id.
Related errors
- Meeting comment like for removing must exist.
- Meeting for adding comment must exist.
- To create reply the comment must exist.
- Meeting comment for editing must exist.
- Meeting comment for removing must exist.
AI-assisted analysis of kgrzybek/modular-monolith-with-ddd@91c8ef24b4 (2026-08-13).
Data as JSON: /api/errors/8075e7c0af7bf323.
Report an issue: GitHub.