fullstackhero/dotnet-starter-kit · error · CustomException
A category with name
Error message
A category with name '{command.Name}' already exists. What it means
CreateCategoryCommandHandler computes the category slug from the name and throws CustomException with HTTP 409 Conflict when an existing category already has that Slug; nothing is persisted. Slug collisions arise from identical or near-identical names.
Solutions
- Use a different category name (or explicit unique slug)
- Check the existing category — reuse or update it instead of creating
- If the duplicate is soft-deleted, restore or purge it first
Example fix
// before
await mediator.Send(new CreateCategoryCommand("Shoes", null, null)); // second time
// after
await mediator.Send(new CreateCategoryCommand("Shoes Outlet", null, null)); Defensive patterns
Strategy: validation
Validate before calling
var existing = await mediator.Send(new SearchCategoriesQuery(name));
if (existing.Items.Any(c => c.Slug == Slugify(name))) throw new InvalidOperationException("Category name already exists."); Type guard
bool IsNonEmptyName(string? n) => !string.IsNullOrWhiteSpace(n);
Try / catch
try { await mediator.Send(new CreateCategoryCommand(name, desc, parentId)); }
catch (CustomException ex) when (ex.StatusCode == HttpStatusCode.Conflict) { /* prompt for a different name */ } Prevention
- Deduplicate names before bulk imports
- Use upsert semantics for idempotent seeding
- Add a DB unique index on (TenantId, Slug) as a last line of defense
When it happens
Trigger: Send/CreateCategory command whose Name slugifies to the Slug of an existing category in the tenant.
Common situations: Re-running an import/seed that creates categories; names differing only by case/punctuation; creating the same category in parallel requests.
Related errors
- A brand with name ' ' already exists.
- Another brand with name
- Cannot delete a category that has child categories. Move or…
- Another category with name
- A product with SKU ' ' already exists.
AI-assisted analysis of fullstackhero/dotnet-starter-kit@3f2959e683 (2026-09-15).
Data as JSON: /api/errors/49713885c646cce7.
Report an issue: GitHub.
Appendix: source
Thrown at src/Modules/Catalog/Modules.Catalog/Features/v1/Categories/CreateCategory/CreateCategoryCommandHandler.cs:36
if (command.ParentCategoryId is { } parentId)
{
bool parentExists = await dbContext.Categories
.AnyAsync(c => c.Id == parentId, cancellationToken)
.ConfigureAwait(false);
if (!parentExists)
{
throw new NotFoundException($"Parent category {parentId} not found.");
}
}
var category = Category.Create(command.Name, command.Description, command.ParentCategoryId);
bool slugTaken = await dbContext.Categories
.AnyAsync(c => c.Slug == category.Slug, cancellationToken)
.ConfigureAwait(false);
if (slugTaken)
{
throw new CustomException(
$"A category with name '{command.Name}' already exists.",
(IEnumerable<string>?)null,
HttpStatusCode.Conflict);
}
dbContext.Categories.Add(category);
await dbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
return category.Id;
}
}
View on GitHub (pinned to 3f2959e683)