fullstackhero/dotnet-starter-kit · error · NotFoundException
Brand not found.
Error message
Brand {query.BrandId} not found. What it means
GetBrandByIdQueryHandler queries dbContext.Brands (AsNoTracking) for the given BrandId and throws NotFoundException when no row matches, which the API surfaces as HTTP 404. Default query filters (soft-delete and tenant scoping) apply, so hidden or foreign-tenant rows look missing.
Solutions
- Confirm the BrandId via the brands list endpoint
- Restore the brand if it was soft-deleted (RestoreBrand endpoint)
- Verify the tenant header matches the tenant owning the brand
Defensive patterns
Strategy: try-catch
Validate before calling
bool exists = brands.Any(b => b.Id == id); // from a recently fetched list
Try / catch
try { var brand = await mediator.Send(new GetBrandByIdQuery(id)); }
catch (NotFoundException) { return Results.NotFound($"Brand {id} not found."); } Prevention
- Avoid persisting brand IDs in long-lived clients without refresh
- Validate IDs belong to the active tenant
- Handle soft-deleted entities explicitly in lookups
When it happens
Trigger: Send/GetBrandById query with an unknown, hard-deleted, soft-deleted, or cross-tenant BrandId.
Common situations: Client cached an ID that was since deleted; user opens a bookmarked URL after the brand was removed; multitenancy header misconfigured so the row is invisible.
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/f12034b6f4190391.
Report an issue: GitHub.
Appendix: source
Thrown at src/Modules/Catalog/Modules.Catalog/Features/v1/Brands/GetBrandById/GetBrandByIdQueryHandler.cs:21
using FSH.Modules.Catalog.Contracts.v1.Brands;
using FSH.Modules.Catalog.Data;
using Mediator;
using Microsoft.EntityFrameworkCore;
namespace FSH.Modules.Catalog.Features.v1.Brands.GetBrandById;
public sealed class GetBrandByIdQueryHandler(CatalogDbContext dbContext)
: IQueryHandler<GetBrandByIdQuery, BrandDto>
{
public async ValueTask<BrandDto> Handle(GetBrandByIdQuery query, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(query);
var brand = await dbContext.Brands
.AsNoTracking()
.FirstOrDefaultAsync(b => b.Id == query.BrandId, cancellationToken)
.ConfigureAwait(false)
?? throw new NotFoundException($"Brand {query.BrandId} not found.");
return new BrandDto(
brand.Id,
brand.Name,
brand.Slug,
brand.Description,
brand.LogoUrl,
brand.CreatedAtUtc,
brand.UpdatedAtUtc,
brand.DeletedOnUtc,
brand.DeletedBy);
}
}
View on GitHub (pinned to 3f2959e683)