{"record":{"id":"7f0818a453edb3ef","repo":"fullstackhero/dotnet-starter-kit","slug":"another-category-with-name-command-name-already-exists","errorCode":null,"errorMessage":"Another category with name '{command.Name}' already exists.","messagePattern":"Another category with name '(.+?)' already exists\\.","errorType":"exception","errorClass":"CustomException","httpStatus":409,"severity":"error","filePath":"src/Modules/Catalog/Modules.Catalog/Features/v1/Categories/UpdateCategory/UpdateCategoryCommandHandler.cs","lineNumber":59,"sourceCode":"                        (IEnumerable<string>?)null,\n                        HttpStatusCode.BadRequest);\n                }\n                cursor = await dbContext.Categories\n                    .Where(c => c.Id == cur)\n                    .Select(c => c.ParentCategoryId)\n                    .FirstOrDefaultAsync(cancellationToken)\n                    .ConfigureAwait(false);\n            }\n        }\n\n        category.Update(command.Name, command.Description, command.ParentCategoryId);\n\n        bool slugTaken = await dbContext.Categories\n            .AnyAsync(c => c.Slug == category.Slug && c.Id != category.Id, cancellationToken)\n            .ConfigureAwait(false);\n        if (slugTaken)\n        {\n            throw new CustomException(\n                $\"Another category with name '{command.Name}' already exists.\",\n                (IEnumerable<string>?)null,\n                HttpStatusCode.Conflict);\n        }\n\n        await dbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false);\n        return category.Id;\n    }\n}\n","sourceCodeStart":41,"sourceCodeEnd":69,"githubUrl":"https://github.com/fullstackhero/dotnet-starter-kit/blob/3f2959e683e9f83f13e55e1678c9119f63c7e8e5/src/Modules/Catalog/Modules.Catalog/Features/v1/Categories/UpdateCategory/UpdateCategoryCommandHandler.cs#L41-L69","documentation":"UpdateCategory checks whether any other category already uses the resulting Slug; if so it throws CustomException with 409 Conflict, using the name in the message because slug is derived from name. It enforces unique category slugs at the application level.","triggerScenarios":"PUT update renaming a category to a name whose generated slug collides with another existing category's slug (excluding itself via c.Id != category.Id).","commonSituations":"Two categories named alike (e.g. 'Shoes (sale)' and 'Shoes sale' slug-collide); renaming a category to match an existing one; race where another user created the same name between page load and save.","solutions":["Choose a different, unique category name.","If duplicates are legitimate, disambiguate the name (add a qualifier) so the slug differs.","Refresh the category list to confirm the conflicting name, then decide which to keep.","Consider surfacing slug uniqueness in the form validator before submission."],"exampleFix":"// before\nawait api.updateCategory({ id, name: 'Electronics' }); // conflicts\n\n// after\nawait api.updateCategory({ id, name: 'Electronics Outlet' }); // unique slug","handlingStrategy":"validation","validationCode":"const others = (await api.listCategories()).items.filter(c => c.id !== editingId);\nconst slug = slugify(payload.name);\nif (others.some(c => c.slug === slug)) {\n  return formError('A category with this name already exists.');\n}","typeGuard":null,"tryCatchPattern":"try { await api.updateCategory(payload); }\ncatch (e) { if (e.status === 409) formError('Name already in use — pick another'); else throw e; }","preventionTips":["Check name uniqueness in the form before submit","Slugify names the same way the server does when pre-checking","Refresh the list before renaming to catch recent duplicates"],"tags":["conflict","duplicate","slug","uniqueness"],"backgroundTag":"file-already-exists","analyzedSha":"3f2959e683e9f83f13e55e1678c9119f63c7e8e5","analyzedAt":"2026-09-15T22:20:53.684Z","contentChangedAt":"2026-09-15T22:20:53.684Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}