{"record":{"id":"f93293977d6409ce","repo":"fullstackhero/dotnet-starter-kit","slug":"parent-category-parentid-not-found","errorCode":null,"errorMessage":"Parent category {parentId} not found.","messagePattern":"Parent category (.+?) not found\\.","errorType":"exception","errorClass":"NotFoundException","httpStatus":404,"severity":"error","filePath":"src/Modules/Catalog/Modules.Catalog/Features/v1/Categories/CreateCategory/CreateCategoryCommandHandler.cs","lineNumber":25,"sourceCode":"using Microsoft.EntityFrameworkCore;\n\nnamespace FSH.Modules.Catalog.Features.v1.Categories.CreateCategory;\n\npublic sealed class CreateCategoryCommandHandler(CatalogDbContext dbContext)\n    : ICommandHandler<CreateCategoryCommand, Guid>\n{\n    public async ValueTask<Guid> Handle(CreateCategoryCommand command, CancellationToken cancellationToken)\n    {\n        ArgumentNullException.ThrowIfNull(command);\n\n        if (command.ParentCategoryId is { } parentId)\n        {\n            bool parentExists = await dbContext.Categories\n                .AnyAsync(c => c.Id == parentId, cancellationToken)\n                .ConfigureAwait(false);\n            if (!parentExists)\n            {\n                throw new NotFoundException($\"Parent category {parentId} not found.\");\n            }\n        }\n\n        var category = Category.Create(command.Name, command.Description, command.ParentCategoryId);\n\n        bool slugTaken = await dbContext.Categories\n            .AnyAsync(c => c.Slug == category.Slug, cancellationToken)\n            .ConfigureAwait(false);\n        if (slugTaken)\n        {\n            throw new CustomException(\n                $\"A category with name '{command.Name}' already exists.\",\n                (IEnumerable<string>?)null,\n                HttpStatusCode.Conflict);\n        }\n\n        dbContext.Categories.Add(category);\n        await dbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false);","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/fullstackhero/dotnet-starter-kit/blob/3f2959e683e9f83f13e55e1678c9119f63c7e8e5/src/Modules/Catalog/Modules.Catalog/Features/v1/Categories/CreateCategory/CreateCategoryCommandHandler.cs#L7-L43","documentation":"CreateCategoryCommandHandler, when command.ParentCategoryId is supplied, verifies the parent exists with an AnyAsync check and throws NotFoundException (HTTP 404) if it does not; the category is not created. Only tenant-visible, non-deleted parent rows count.","triggerScenarios":"Send/CreateCategory command with a non-null ParentCategoryId that matches no category in the current tenant.","commonSituations":"Client sends a stale parent ID after the parent was deleted; ID from another tenant; typo or swapped GUID fields in the request body.","solutions":["Verify the parent category ID via the categories list endpoint","Create the category without a ParentCategoryId (top-level) if no parent is needed","Re-create the parent category first if it was deleted"],"exampleFix":"// before\nnew CreateCategoryCommand(\"Sub\", null, unknownParentId);\n// after\nvar parents = await mediator.Send(new SearchCategoriesQuery(\"Parent\")); // pick a valid ID\nnew CreateCategoryCommand(\"Sub\", null, parents.Items.First().Id);","handlingStrategy":"validation","validationCode":"if (parentId is not null) {\n  var parent = await mediator.Send(new GetCategoryByIdQuery(parentId)); // throws 404 if invalid\n}","typeGuard":null,"tryCatchPattern":"try { await mediator.Send(new CreateCategoryCommand(name, desc, parentId)); }\ncatch (NotFoundException) { /* parent gone — clear parent selector and retry top-level */ }","preventionTips":["Populate parent selectors from live API data, never cached IDs","Null out ParentCategoryId when the parent lookup fails","Validate parent/child IDs belong to the same tenant"],"tags":["not-found","http-404","category","parent"],"backgroundTag":"entity-not-found","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"}