fullstackhero/dotnet-starter-kit · warning · NotFoundException
Product not found.
Error message
Product {command.ProductId} not found. What it means
AddProductImage loads the product by command.ProductId and throws NotFoundException when no product matches, so an image cannot be attached to a non-existent aggregate. Soft-delete query filters apply, so deleted products also report 'not found'.
Solutions
- Verify the product exists: SELECT * FROM "Products" WHERE "Id" = '<id>'.
- Re-open the product page and retry the image upload from the current product.
- Check the product is not soft-deleted; restore it if needed.
- Confirm tenant context matches the product's tenant.
Defensive patterns
Strategy: try-catch
Validate before calling
const p = await api.getProduct(productId).catch(() => null);
if (!p) return alert('Product no longer exists'); Type guard
const isGuid = (v) => typeof v === 'string' && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(v); Try / catch
try { await api.addProductImage(productId, file); }
catch (e) { if (e.status === 404) show('Product was deleted'); else throw e; } Prevention
- Re-open the product right before uploading images
- Handle deletion of the product while the upload wizard is open
- Validate id format before sending
When it happens
Trigger: POST add-image for a ProductId that: (1) was deleted, (2) is a typo/fabricated Guid, (3) belongs to another tenant.
Common situations: Client kept the upload wizard open while the product was deleted elsewhere; wrong id mapped from a list; testing with ids from a different database.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
AI-assisted analysis of fullstackhero/dotnet-starter-kit@3f2959e683 (2026-09-15).
Data as JSON: /api/errors/203f5367e2221938.
Report an issue: GitHub.
Appendix: source
Thrown at src/Modules/Catalog/Modules.Catalog/Features/v1/Products/AddProductImage/AddProductImageCommandHandler.cs:20
using FSH.Modules.Catalog.Contracts.Dtos;
using FSH.Modules.Catalog.Contracts.v1.Products.AddProductImage;
using FSH.Modules.Catalog.Data;
using Mediator;
using Microsoft.EntityFrameworkCore;
namespace FSH.Modules.Catalog.Features.v1.Products.AddProductImage;
public sealed class AddProductImageCommandHandler(CatalogDbContext dbContext)
: ICommandHandler<AddProductImageCommand, ProductImageDto>
{
public async ValueTask<ProductImageDto> Handle(AddProductImageCommand command, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(command);
var product = await dbContext.Products
.FirstOrDefaultAsync(p => p.Id == command.ProductId, cancellationToken)
.ConfigureAwait(false)
?? throw new NotFoundException($"Product {command.ProductId} not found.");
var image = product.AddImage(command.FileAssetId, command.Url);
await dbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
return new ProductImageDto(image.Id, image.FileAssetId, image.Url, image.IsThumbnail, image.SortOrder, image.CreatedAtUtc);
}
}
View on GitHub (pinned to 3f2959e683)