fullstackhero/dotnet-starter-kit · error · NotFoundException
User Not Found.
Error message
User Not Found.
What it means
UserStatusService.BuildToggleContextAsync throws NotFoundException("User Not Found.") when the target user id from the toggle-status command does not match any ASP.NET Identity user row in the current tenant's database. It is the guard before any status change is applied, thrown via EF Core's FirstOrDefaultAsync over userManager.Users.
Solutions
- Verify the userId in the request actually exists: query AspNetUsers (filtered by the active tenant) for that id.
- Confirm the request is sent with the correct tenant identifier/header so the tenant query filter includes the user.
- Refresh the user list on the client so the id is not stale/deleted.
- If the user should exist, run the DbMigrator with seed or restore the record.
Example fix
// before
await mediator.Send(new ToggleUserStatusCommand { UserId = "dead-id" });
// after
var user = await userManager.Users.FirstOrDefaultAsync(u => u.Id == id);
if (user is not null)
await mediator.Send(new ToggleUserStatusCommand { UserId = user.Id }); Defensive patterns
Strategy: try-catch
Validate before calling
var exists = await userManager.Users.AnyAsync(u => u.Id == userId, ct);
if (!exists) throw new ValidationException($"User {userId} does not exist."); Try / catch
try { await mediator.Send(cmd); }
catch (NotFoundException) { /* show 'user no longer exists' UI state */ } Prevention
- Resolve user ids from a fresh server-side lookup rather than cached lists.
- Always send the correct tenant header/id in multitenant calls.
- Handle user deletion events by invalidating client caches.
- Validate user existence in the command validator before dispatch.
When it happens
Trigger: Calling the toggle-user-status endpoint/command with a userId that does not exist in the database, that belongs to a different tenant (tenant filter excludes it), or that was deleted after the caller fetched its id.
Common situations: Stale client-side caches listing deleted users; running a query against the wrong tenant database in a multitenant deployment; copying a user id from another environment (dev/staging/prod); typos in manually built API requests.
Understand the failure class
Background: "User not found", "Invalid user", and "does not exist": what missing-user lookup errors mean across Rocket.Chat, LiteLLM, Phabricator, rustfs, and pnpm — this error's family across 10 libraries.
Related errors
AI-assisted analysis of fullstackhero/dotnet-starter-kit@3f2959e683 (2026-09-15).
Data as JSON: /api/errors/aa0c6fce6c80c49f.
Report an issue: GitHub.
Appendix: source
Thrown at src/Modules/Identity/Modules.Identity/Services/UserStatusService.cs:64
private async Task<ToggleStatusContext> BuildToggleContextAsync(
string userId,
bool activateUser,
CancellationToken cancellationToken)
{
var actorId = currentUser.GetUserId();
if (actorId == Guid.Empty)
{
throw new UnauthorizedException("authenticated user required to toggle status");
}
var actor = await userManager.FindByIdAsync(actorId.ToString())
?? throw new UnauthorizedException("current user not found");
var targetUser = await userManager.Users
.Where(u => u.Id == userId)
.FirstOrDefaultAsync(cancellationToken)
?? throw new NotFoundException("User Not Found.");
return new ToggleStatusContext(
ActorId: actorId,
Actor: actor,
TargetUser: targetUser,
ActivateUser: activateUser,
TenantId: multiTenantContextAccessor?.MultiTenantContext?.TenantInfo?.Id);
}
private async Task ValidateTogglePermissionsAsync(
ToggleStatusContext context,
CancellationToken cancellationToken)
{
if (!await userManager.IsInRoleAsync(context.Actor, RoleConstants.Admin))
{
await AuditPolicyFailureAsync(context, "ActorNotAdmin", cancellationToken);
throw new ForbiddenException("Only administrators can change user status.");
}View on GitHub (pinned to 3f2959e683)