{"record":{"id":"852404df4fa8c104","repo":"fullstackhero/dotnet-starter-kit","slug":"group-with-id-query-groupid-not-found","errorCode":null,"errorMessage":"Group with ID '{query.GroupId}' not found.","messagePattern":"Group with ID '(.+?)' not found\\.","errorType":"exception","errorClass":"NotFoundException","httpStatus":404,"severity":"error","filePath":"src/Modules/Identity/Modules.Identity/Features/v1/Groups/GetGroupMembers/GetGroupMembersQueryHandler.cs","lineNumber":28,"sourceCode":"public sealed class GetGroupMembersQueryHandler : IQueryHandler<GetGroupMembersQuery, IEnumerable<GroupMemberDto>>\n{\n    private readonly IdentityDbContext _dbContext;\n\n    public GetGroupMembersQueryHandler(IdentityDbContext dbContext)\n    {\n        _dbContext = dbContext;\n    }\n\n    public async ValueTask<IEnumerable<GroupMemberDto>> Handle(GetGroupMembersQuery query, CancellationToken cancellationToken)\n    {\n        // Validate group exists\n        var groupExists = await _dbContext.Groups\n            .AsNoTracking()\n            .AnyAsync(g => g.Id == query.GroupId, cancellationToken);\n\n        if (!groupExists)\n        {\n            throw new NotFoundException($\"Group with ID '{query.GroupId}' not found.\");\n        }\n\n        // Get memberships with user info\n        var memberships = await _dbContext.UserGroups\n            .AsNoTracking()\n            .Where(ug => ug.GroupId == query.GroupId)\n            .Join(\n                _dbContext.Users,\n                ug => ug.UserId,\n                u => u.Id,\n                (ug, u) => new GroupMemberDto\n                {\n                    UserId = u.Id,\n                    UserName = u.UserName,\n                    Email = u.Email,\n                    FirstName = u.FirstName,\n                    LastName = u.LastName,\n                    AddedAt = ug.AddedAt,","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/fullstackhero/dotnet-starter-kit/blob/3f2959e683e9f83f13e55e1678c9119f63c7e8e5/src/Modules/Identity/Modules.Identity/Features/v1/Groups/GetGroupMembers/GetGroupMembersQueryHandler.cs#L10-L46","documentation":"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.","triggerScenarios":"GET /groups/{groupId}/members where groupId is deleted, nonexistent, cross-tenant, or Guid.Empty.","commonSituations":"Members page open while the group is deleted elsewhere; polling/realtime refresh using a stale id; copy-pasted ids across environments.","solutions":["Re-fetch the group list and pick a valid id","In the UI, catch 404 and route back to the groups list","Validate the id format (non-empty Guid) client-side before calling"],"exampleFix":"// before\nconst members = await api.GetGroupMembers(groupId);\n// after\ntry { const members = await api.GetGroupMembers(groupId); }\ncatch (e) { if (is404(e)) navigate('/groups'); else throw e; }","handlingStrategy":"try-catch","validationCode":"var exists = (await api.SearchGroups(name)).Any(g => g.Id == groupId);\nif (!exists) navigate('/groups');","typeGuard":"const isNonEmptyGuid = (v: unknown): v is string => typeof v === 'string' && v !== '00000000-0000-0000-0000-000000000000';","tryCatchPattern":"try { const members = await api.GetGroupMembers(groupId); }\ncatch (e) { if (is404(e)) navigate('/groups'); else throw e; }","preventionTips":["Stop polling/refresh jobs once a group is deleted","Re-check group existence on realtime delete notifications","Validate groupId query params"],"tags":["http-404","identity","groups","members"],"backgroundTag":"entity-not-found","analyzedSha":"3f2959e683e9f83f13e55e1678c9119f63c7e8e5","analyzedAt":"2026-09-15T22:20:53.684Z","contentChangedAt":"2026-09-15T22:20:53.684Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}