{"record":{"id":"8e67bda9593ac2dd","repo":"fullstackhero/dotnet-starter-kit","slug":"category-command-categoryid-not-found-8e67bd","errorCode":null,"errorMessage":"Category {command.CategoryId} not found.","messagePattern":"Category (.+?) not found\\.","errorType":"exception","errorClass":"NotFoundException","httpStatus":404,"severity":"error","filePath":"src/Modules/Catalog/Modules.Catalog/Features/v1/Products/CreateProduct/CreateProductCommandHandler.cs","lineNumber":32,"sourceCode":"{\n    public async ValueTask<Guid> Handle(CreateProductCommand command, CancellationToken cancellationToken)\n    {\n        ArgumentNullException.ThrowIfNull(command);\n\n        bool brandExists = await dbContext.Brands\n            .AnyAsync(b => b.Id == command.BrandId, cancellationToken)\n            .ConfigureAwait(false);\n        if (!brandExists)\n        {\n            throw new NotFoundException($\"Brand {command.BrandId} not found.\");\n        }\n\n        bool categoryExists = await dbContext.Categories\n            .AnyAsync(c => c.Id == command.CategoryId, cancellationToken)\n            .ConfigureAwait(false);\n        if (!categoryExists)\n        {\n            throw new NotFoundException($\"Category {command.CategoryId} not found.\");\n        }\n\n        var product = Product.Create(\n            command.Sku,\n            command.Name,\n            command.Description,\n            command.BrandId,\n            command.CategoryId,\n            new Money(command.PriceAmount, command.PriceCurrency),\n            command.Stock);\n\n        bool skuTaken = await dbContext.Products\n            .AnyAsync(p => p.Sku == product.Sku, cancellationToken)\n            .ConfigureAwait(false);\n        if (skuTaken)\n        {\n            throw new CustomException(\n                $\"A product with SKU '{product.Sku}' already exists.\",","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/fullstackhero/dotnet-starter-kit/blob/3f2959e683e9f83f13e55e1678c9119f63c7e8e5/src/Modules/Catalog/Modules.Catalog/Features/v1/Products/CreateProduct/CreateProductCommandHandler.cs#L14-L50","documentation":"CreateProductCommandHandler verifies the referenced Category exists before creating a Product. If no Category row matches command.CategoryId, it throws NotFoundException, mapped to HTTP 404. Like the brand check, it validates the FK relationship explicitly instead of relying on a DB constraint failure.","triggerScenarios":"POST /products (v1) with a CategoryId that does not exist in the Categories table — deleted category, category in another tenant, or an invalid/mistyped identifier.","commonSituations":"Stale category pickers in clients after a category was removed; seed data differing between environments; tenant header mismatch hiding the category row.","solutions":["Verify the CategoryId exists via the categories list/get endpoint before creating the product.","Recreate or reassign to a valid category if the original was deleted.","Ensure the request targets the correct tenant so the category is not filtered out.","Confirm the client is calling the intended environment (dev/staging/prod) with matching data."],"exampleFix":"// before\nawait api.createProduct({ sku: 'X', name: 'X', categoryId: form.categoryId });\n// after\nconst categories = await api.listCategories();\nif (!categories.items.some(c => c.id === form.categoryId)) {\n  throw new Error('Pick a valid category before submitting');\n}\nawait api.createProduct({ sku: 'X', name: 'X', categoryId: form.categoryId });","handlingStrategy":"validation","validationCode":"const categories = await api.listCategories();\nif (!categories.items.some(c => c.id === categoryId)) {\n  throw new Error(`Category ${categoryId} does not exist`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await api.createProduct(payload);\n} catch (e) {\n  if (e.status === 404 && /Category .* not found/.test(e.message ?? '')) {\n    showFieldError('categoryId', 'Selected category no longer exists');\n    return;\n  }\n  throw e;\n}","preventionTips":["Drive category selection from the API's current category list","Refresh category options when the tenant or environment changes","Disable stale category options removed by other users"],"tags":["ef-core","not-found","foreign-key","catalog","http-404"],"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"}