fullstackhero/dotnet-starter-kit · error · CustomException
A closed ticket cannot accept new comments — reopen it…
Error message
A closed ticket cannot accept new comments — reopen it first.
What it means
Ticket.AddComment rejects new comments on a Closed ticket, throwing CustomException with HTTP 409 Conflict. Commenting is only allowed while the ticket is active; it must be reopened to continue the discussion. This guards the closed ticket's frozen conversation thread.
Solutions
- Reopen the ticket, then add the comment.
- Handle 409 in the client, refresh the ticket, and show 'Reopen to comment'.
- Check ticket status when loading the comment form and hide/disable it for closed tickets.
- If the reply must be preserved, reopen the ticket programmatically before submitting the comment.
Example fix
// before
ticket.AddComment(authorUserId, body); // 409 if closed
// after
if (ticket.Status == TicketStatus.Closed)
{
ticket.Reopen();
}
ticket.AddComment(authorUserId, body); Defensive patterns
Strategy: validation
Validate before calling
if (ticket.status === TicketStatus.Closed) {
throw new Error('Reopen the ticket to comment.');
}
ticket.addComment(authorUserId, body); Type guard
bool CanComment(Ticket t) => t.Status != TicketStatus.Closed;
Try / catch
try
{
await api.addComment(ticketId, body);
}
catch (err) {
if (err.status === 409) {
await api.reopen(ticketId);
await api.addComment(ticketId, body);
} else { throw err; }
} Prevention
- Hide/disable the comment box for closed tickets and refresh status when the detail view regains focus.
- Warn users their reply may hit a closed ticket before submitting after long idle.
- Treat 409 as 'reopen to comment' and surface that action in the UI.
- For email/automation integrations, check status before piping replies into comments.
When it happens
Trigger: Calling AddComment (or the add-comment endpoint) on a ticket with Status == TicketStatus.Closed, e.g. replying from a stale comment form after the ticket was closed.
Common situations: User kept a comment box open while an agent closed the ticket; email/automation piping replies into closed tickets; UI not refreshing ticket status after close.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- A closed ticket cannot be resolved — reopen it first.
- Only a resolved ticket can be closed — current status is
- Cannot a ticket in status — reopen it first.
- A closed ticket cannot be edited — reopen it first.
- Top-up request cannot be rejected because it is (only…
AI-assisted analysis of fullstackhero/dotnet-starter-kit@3f2959e683 (2026-09-15).
Data as JSON: /api/errors/e79bdb1fe281ed50.
Report an issue: GitHub.
Appendix: source
Thrown at src/Modules/Tickets/Modules.Tickets/Domain/Ticket.cs:201
{
return;
}
// Clear the close timestamp so a fresh resolution gets its own audit window.
ClosedAtUtc = null;
ResolvedAtUtc = null;
ResolutionNote = null;
UpdatedAtUtc = DateTime.UtcNow;
// Reopened tickets fall back to whatever assignment state they had:
// if still assigned, InProgress; if not, Open.
TransitionStatus(AssignedToUserId is null ? TicketStatus.Open : TicketStatus.InProgress);
}
public Guid AddComment(Guid authorUserId, string body)
{
if (Status == TicketStatus.Closed)
{
throw new CustomException(
"A closed ticket cannot accept new comments — reopen it first.",
(IEnumerable<string>?)null,
HttpStatusCode.Conflict);
}
var comment = TicketComment.Create(Id, authorUserId, body);
_comments.Add(comment);
UpdatedAtUtc = DateTime.UtcNow;
AddDomainEvent(DomainEvent.Create<TicketCommentAddedDomainEvent>(
(id, ts) => new TicketCommentAddedDomainEvent(Id, comment.Id, authorUserId, id, ts)));
return comment.Id;
}
private void TransitionStatus(TicketStatus next)
{
if (next == Status)View on GitHub (pinned to 3f2959e683)