kgrzybek/modular-monolith-with-ddd · error · InvalidCommandException
Meeting for adding comment must exist.
Error message
Meeting for adding comment must exist.
What it means
Thrown by AddMeetingCommentCommandHandler when _meetingRepository.GetByIdAsync returns null for the supplied MeetingId. Commenting requires a target meeting aggregate; if none is found the command is rejected as InvalidCommandException (HTTP 400). The meeting is also used downstream to resolve the meeting group and commenting configuration.
Source
Thrown at src/Modules/Meetings/Application/MeetingComments/AddMeetingComment/AddMeetingCommentCommandHandler.cs:38
IMeetingRepository meetingRepository,
IMeetingCommentRepository meetingCommentRepository,
IMeetingGroupRepository meetingGroupRepository,
IMeetingCommentingConfigurationRepository meetingCommentingConfigurationRepository,
IMemberContext memberContext)
{
_meetingGroupRepository = meetingGroupRepository;
_meetingRepository = meetingRepository;
_meetingCommentingConfigurationRepository = meetingCommentingConfigurationRepository;
_meetingCommentRepository = meetingCommentRepository;
_memberContext = memberContext;
}
public async Task<Guid> Handle(AddMeetingCommentCommand command, CancellationToken cancellationToken)
{
var meeting = await _meetingRepository.GetByIdAsync(new MeetingId(command.MeetingId));
if (meeting == null)
{
throw new InvalidCommandException(["Meeting for adding comment must exist."]);
}
var meetingGroup = await _meetingGroupRepository.GetByIdAsync(meeting.GetMeetingGroupId());
var meetingCommentingConfiguration = await _meetingCommentingConfigurationRepository.GetByMeetingIdAsync(new MeetingId(command.MeetingId));
var meetingComment = meeting.AddComment(_memberContext.MemberId, command.Comment, meetingGroup, meetingCommentingConfiguration);
await _meetingCommentRepository.AddAsync(meetingComment);
return meetingComment.Id.Value;
}
}
}View on GitHub (pinned to 91c8ef24b4)
Solutions
- Validate the MeetingId is a non-empty, existing meeting before allowing the user to comment.
- Refresh the client's meeting list so stale ids are not submitted.
- In the controller, check meeting existence via a query and return 404 instead of dispatching.
- Handle InvalidCommandException at the API boundary and return 400/404.
Example fix
// before
var commentId = await _commandDispatcher.SendAsync(new AddMeetingCommentCommand(meetingId, text));
// after
var meeting = await _meetingQueries.GetMeetingAsync(meetingId);
if (meeting is null) return NotFound("Meeting not found.");
var commentId = await _commandDispatcher.SendAsync(new AddMeetingCommentCommand(meetingId, text)); Defensive patterns
Strategy: validation
Validate before calling
var meeting = await _meetingQueries.GetMeetingAsync(meetingId);
if (meeting is null) return NotFound("Meeting not found.");
var id = await _commandDispatcher.SendAsync(new AddMeetingCommentCommand(meetingId, text)); Type guard
public static bool IsValidMeetingId(AddMeetingCommentCommand c) =>
c.MeetingId != Guid.Empty && !string.IsNullOrWhiteSpace(c.Comment); 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
- Refresh the client's meeting list so deleted meetings are not referenced.
- Disable the comment box when the meeting is not loaded.
- Validate non-empty Guid and non-empty comment client-side.
When it happens
Trigger: Posting AddMeetingCommentCommand with a MeetingId that does not correspond to any meeting: wrong/empty Guid, meeting not yet created, meeting in a different tenant/partition, or a stale client reference.
Common situations: Mobile/web client retains a meeting link after the meeting was deleted; concurrency where the comment is submitted during creation; tests using a fabricated id.
Related errors
- To add like the comment must exist.
- To create reply the comment must exist.
- Meeting comment for editing must exist.
- Meeting comment for removing must exist.
- Meeting comment like for removing must exist.
AI-assisted analysis of kgrzybek/modular-monolith-with-ddd@91c8ef24b4 (2026-08-13).
Data as JSON: /api/errors/9f8b9f42392e9b44.
Report an issue: GitHub.