fullstackhero/dotnet-starter-kit · error · NotFoundException

Group with ID ' ' not found.

Error message

Group with ID '{query.GroupId}' not found.

What it means

Thrown by GetGroupMembersQueryHandler after an AsNoTracking AnyAsync existence check on query.GroupId returns false. The guard validates the group exists before listing its members; failure means the ID is unknown/stale or filtered out by tenant isolation.

Solutions

  1. Re-fetch the group list and pick a valid id
  2. In the UI, catch 404 and route back to the groups list
  3. Validate the id format (non-empty Guid) client-side before calling

Example fix

// before
const members = await api.GetGroupMembers(groupId);
// after
try { const members = await api.GetGroupMembers(groupId); }
catch (e) { if (is404(e)) navigate('/groups'); else throw e; }
Defensive patterns

Strategy: try-catch

Validate before calling

var exists = (await api.SearchGroups(name)).Any(g => g.Id == groupId);
if (!exists) navigate('/groups');

Type guard

const isNonEmptyGuid = (v: unknown): v is string => typeof v === 'string' && v !== '00000000-0000-0000-0000-000000000000';

Try / catch

try { const members = await api.GetGroupMembers(groupId); }
catch (e) { if (is404(e)) navigate('/groups'); else throw e; }

Prevention

When it happens

Trigger: GET /groups/{groupId}/members where groupId is deleted, nonexistent, cross-tenant, or Guid.Empty.

Common situations: Members page open while the group is deleted elsewhere; polling/realtime refresh using a stale id; copy-pasted ids across environments.

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/852404df4fa8c104. Report an issue: GitHub.

Appendix: source

Thrown at src/Modules/Identity/Modules.Identity/Features/v1/Groups/GetGroupMembers/GetGroupMembersQueryHandler.cs:28

public sealed class GetGroupMembersQueryHandler : IQueryHandler<GetGroupMembersQuery, IEnumerable<GroupMemberDto>>
{
    private readonly IdentityDbContext _dbContext;

    public GetGroupMembersQueryHandler(IdentityDbContext dbContext)
    {
        _dbContext = dbContext;
    }

    public async ValueTask<IEnumerable<GroupMemberDto>> Handle(GetGroupMembersQuery query, CancellationToken cancellationToken)
    {
        // Validate group exists
        var groupExists = await _dbContext.Groups
            .AsNoTracking()
            .AnyAsync(g => g.Id == query.GroupId, cancellationToken);

        if (!groupExists)
        {
            throw new NotFoundException($"Group with ID '{query.GroupId}' not found.");
        }

        // Get memberships with user info
        var memberships = await _dbContext.UserGroups
            .AsNoTracking()
            .Where(ug => ug.GroupId == query.GroupId)
            .Join(
                _dbContext.Users,
                ug => ug.UserId,
                u => u.Id,
                (ug, u) => new GroupMemberDto
                {
                    UserId = u.Id,
                    UserName = u.UserName,
                    Email = u.Email,
                    FirstName = u.FirstName,
                    LastName = u.LastName,
                    AddedAt = ug.AddedAt,

View on GitHub (pinned to 3f2959e683)