{"record":{"id":"f1010c58f5a46016","repo":"fullstackhero/dotnet-starter-kit","slug":"group-with-id-command-groupid-not-found","errorCode":null,"errorMessage":"Group with ID '{command.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/AddUsersToGroup/AddUsersToGroupCommandHandler.cs","lineNumber":35,"sourceCode":"\n    public AddUsersToGroupCommandHandler(IdentityDbContext dbContext, ICurrentUser currentUser, IUserPermissionService userPermissionService)\n    {\n        _dbContext = dbContext;\n        _currentUser = currentUser;\n        _userPermissionService = userPermissionService;\n    }\n\n    public async ValueTask<AddUsersToGroupResponse> Handle(AddUsersToGroupCommand command, CancellationToken cancellationToken)\n    {\n        ArgumentNullException.ThrowIfNull(command);\n\n        // Validate group exists\n        var groupExists = await _dbContext.Groups\n            .AnyAsync(g => g.Id == command.GroupId, cancellationToken);\n\n        if (!groupExists)\n        {\n            throw new NotFoundException($\"Group with ID '{command.GroupId}' not found.\");\n        }\n\n        // Validate user IDs exist\n        var existingUserIds = await _dbContext.Users\n            .Where(u => command.UserIds.Contains(u.Id))\n            .Select(u => u.Id)\n            .ToListAsync(cancellationToken);\n\n        var invalidUserIds = command.UserIds.Except(existingUserIds).ToList();\n        if (invalidUserIds.Count > 0)\n        {\n            throw new NotFoundException($\"Users not found: {string.Join(\", \", invalidUserIds)}\");\n        }\n\n        // Get existing memberships\n        var existingMemberships = await _dbContext.UserGroups\n            .Where(ug => ug.GroupId == command.GroupId && command.UserIds.Contains(ug.UserId))\n            .Select(ug => ug.UserId)","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/fullstackhero/dotnet-starter-kit/blob/3f2959e683e9f83f13e55e1678c9119f63c7e8e5/src/Modules/Identity/Modules.Identity/Features/v1/Groups/AddUsersToGroup/AddUsersToGroupCommandHandler.cs#L17-L53","documentation":"The AddUsersToGroup command handler verifies the target group exists in the current tenant's DbContext before touching memberships. If no Group row matches command.GroupId, it throws NotFoundException, which the API maps to HTTP 404. This is an existence guard, not an authorization failure.","triggerScenarios":"POST to the add-users-to-group endpoint with a GroupId that was deleted, never existed, belongs to another tenant, or a GUID typo (including empty/default Guid).","commonSituations":"Client cached a stale group id after the group was deleted; cross-tenant id reuse when copying request payloads between environments; frontend passing undefined coerced to Guid.Empty.","solutions":["Fetch the group list via GET /groups and use a valid GroupId from the current tenant","If migrating data between tenants, recreate the group first or move it, then retry","Correct the client so group ids come from the tenant-scoped list, never hardcoded"],"exampleFix":"// before\nawait client.PostAsync($\"/groups/{someStaleId}/users\", body);\n// after\nvar groups = await GET list of groups; var id = groups.First(g => g.Name == \"Admins\").Id;\nawait client.PostAsync($\"/groups/{id}/users\", body);","handlingStrategy":"try-catch","validationCode":"var exists = (await api.SearchGroups(name)).Any(g => g.Id == groupId);\nif (!exists) throw new InvalidOperationException($\"Group {groupId} not found in tenant\");","typeGuard":"bool IsValidGroup(GroupDto? g) => g is not null && g.Id != Guid.Empty;","tryCatchPattern":"try { await api.AddUsersToGroup(groupId, userIds); }\ncatch (ApiException e) when (e.Status == 404) { logger.LogWarning(\"Group {GroupId} not found\", groupId); }","preventionTips":["Always source GroupId from the tenant-scoped groups list","Never hardcode group ids across environments","Clear client caches after group deletion"],"tags":["http-404","identity","groups","tenant-isolation"],"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"}