fullstackhero/dotnet-starter-kit · warning · NotFoundException
roles not found
Error message
roles not found
What it means
Thrown by GetUserRolesAsync when the role table query returns null, which in practice can only happen if the roles query yields nothing to the null-coalescing check (an empty roles list should normally never be null). It signals that no roles are available in the current tenant/database.
Solutions
- Run the seeder: `dotnet run --project src/Host/FSH.Starter.DbMigrator -- apply --seed`.
- Verify the Roles table contains rows for the current tenant.
- If seeding is intentionally skipped, treat an empty role list as valid and skip the null-coalescing throw.
- Check connection strings to confirm you are on the expected database.
Example fix
// before: treats empty role list as not found
var roles = await roleManager.Roles.AsNoTracking().ToListAsync(ct) ?? throw new NotFoundException("roles not found");
// after: empty list is valid
var roles = await roleManager.Roles.AsNoTracking().ToListAsync(ct); Defensive patterns
Strategy: fallback
Validate before calling
// confirm roles exist before expecting role data
const roleCount = await apiFetch("/api/v1/roles").then(r => r.length); Try / catch
try { roles = await getUserRoles(userId); } catch (e) {
if (/roles not found/i.test(e.message)) return []; // degrade gracefully for seeded-later DBs
throw e;
} Prevention
- Always run the DbMigrator with --seed in new environments.
- Verify the Roles table is populated after provisioning.
- Pin role seeding to deployment checks so empty role tables are detected early.
When it happens
Trigger: Calling GET user-roles in a freshly provisioned database where identity seeding (role creation) never ran, or against a tenant with no roles provisioned.
Common situations: Skipping the DbMigrator seed step (`--seed`) in a new environment; a migration applied without role data; pointing the API at an empty database.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
- Administrators cannot remove their own admin role.
- operation failed
- role not found
- Role store not configured. Ensure .AddRoles
- Roles not found
AI-assisted analysis of fullstackhero/dotnet-starter-kit@3f2959e683 (2026-09-15).
Data as JSON: /api/errors/f3b4ef33dc67d3a5.
Report an issue: GitHub.
Appendix: source
Thrown at src/Modules/Identity/Modules.Identity/Services/UserRoleService.cs:50
var assignedRoles = await ProcessRoleAssignmentsAsync(user, userRoles);
await RaiseRolesAssignedEventAsync(user, assignedRoles, cancellationToken);
// Any role mutation (add or remove) invalidates the cached permission set; flush
// unconditionally rather than gating on assignedRoles, which only tracks additions.
await userPermissionService.InvalidatePermissionCacheAsync(userId, cancellationToken).ConfigureAwait(false);
return "User Roles Updated Successfully.";
}
public async Task<List<UserRoleDto>> GetUserRolesAsync(string userId, CancellationToken cancellationToken)
{
var user = await userManager.FindByIdAsync(userId)
?? throw new NotFoundException("user not found");
var roles = await roleManager.Roles.AsNoTracking().ToListAsync(cancellationToken)
?? throw new NotFoundException("roles not found");
// Single membership query instead of one IsInRoleAsync round-trip per role.
var memberships = await userManager.GetRolesAsync(user);
var membershipSet = new HashSet<string>(memberships, StringComparer.OrdinalIgnoreCase);
var userRoles = new List<UserRoleDto>();
foreach (var role in roles)
{
userRoles.Add(new UserRoleDto
{
RoleId = role.Id,
RoleName = role.Name,
Description = role.Description,
Enabled = membershipSet.Contains(role.Name!)
});
}
return userRoles;View on GitHub (pinned to 3f2959e683)