dotnet/eShop · warning · OrderingDomainException
Request with {id} already exists
Error message
Request with {id} already exists What it means
Thrown by RequestManager.CreateRequestForCommandAsync when a ClientRequest row with the given Guid id already exists. RequestManager implements the idempotency pattern: each command carries a unique request id, and the first time it is processed a ClientRequest is recorded. A second attempt with the same id is treated as a duplicate and rejected with an OrderingDomainException before the handler runs.
Source
Thrown at src/Ordering.Infrastructure/Idempotency/RequestManager.cs:26
{
_context = context ?? throw new ArgumentNullException(nameof(context));
}
public async Task<bool> ExistAsync(Guid id)
{
var request = await _context.
FindAsync<ClientRequest>(id);
return request != null;
}
public async Task CreateRequestForCommandAsync<T>(Guid id)
{
var exists = await ExistAsync(id);
var request = exists ?
throw new OrderingDomainException($"Request with {id} already exists") :
new ClientRequest()
{
Id = id,
Name = typeof(T).Name,
Time = DateTime.UtcNow
};
_context.Add(request);
await _context.SaveChangesAsync();
}
}
View on GitHub (pinned to 9b4f9434f4)
Solutions
- Treat this exception as expected for duplicate delivery: catch OrderingDomainException from CreateRequestForCommandAsync and return the previously-completed result (or ack) instead of erroring — the work was already done.
- Generate a fresh request id per logical command attempt on the client, and only reuse the id when deliberately retrying the SAME command for idempotency.
- Ensure integration tests truncate/clear the ClientRequests table or use unique ids per run.
- Verify the queue/dead-letter config is not redelivering long-after the command succeeded.
Example fix
// before
await _requestManager.CreateRequestForCommandAsync<CreateOrderCommand>(id);
await _mediator.Send(command);
// after
try {
await _requestManager.CreateRequestForCommandAsync<CreateOrderCommand>(id);
} catch (OrderingDomainException) {
return; // duplicate delivery — command already processed, idempotent ack
}
await _mediator.Send(command); Defensive patterns
Strategy: try-catch
Validate before calling
if (await requestManager.ExistAsync(id)) {
// duplicate delivery — skip processing, return prior result
return;
} Type guard
static bool IsDuplicateRequest(bool exists) => exists;
Try / catch
try {
await requestManager.CreateRequestForCommandAsync<CreateOrderCommand>(id);
} catch (OrderingDomainException) {
// command already handled on a previous delivery — ack/idempotent return
return;
} Prevention
- Treat the duplicate-request exception as expected, not as an error.
- Generate fresh request ids per logical attempt; reuse only for explicit retries.
- Clear the ClientRequests table (or use unique ids) in integration tests.
- Acknowledge/redeliver-safe: design handlers to be idempotent beyond the RequestManager check.
When it happens
Trigger: The same command (same request id) is dispatched more than once — e.g. a client retry, a message-broker redelivery, or a saga re-sending. CreateRequestForCommandAsync is called by a CreateOrderCommandHandler behavior that checks ExistAsync first; on a hit it throws, preventing duplicate order creation.
Common situations: gRPC/HTTP client retrying on timeout after the server already processed the command; message queue redelivering the integration event; integration tests reusing a fixed request id across runs without clearing the Request table; a network blip causing the client to resend.
Related errors
- Is not possible to change the order status from {OrderStatus
- Invalid number of units
- The total of order item is lower than applied discount
- Discount is not valid
- Invalid units
AI-assisted analysis of dotnet/eShop@9b4f9434f4 (2026-08-13).
Data as JSON: /api/errors/8dd1c6bc8cbbd6a2.
Report an issue: GitHub.