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

  1. Verify the product exists: SELECT * FROM "Products" WHERE "Id" = '<id>'.
  2. Re-open the product page and retry the image upload from the current product.
  3. Check the product is not soft-deleted; restore it if needed.
  4. 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

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)