fullstackhero/dotnet-starter-kit · error · NotFoundException

Group with ID ' ' not found.

Error message

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

What it means

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.

Solutions

  1. Fetch the group list via GET /groups and use a valid GroupId from the current tenant
  2. If migrating data between tenants, recreate the group first or move it, then retry
  3. Correct the client so group ids come from the tenant-scoped list, never hardcoded

Example fix

// before
await client.PostAsync($"/groups/{someStaleId}/users", body);
// after
var groups = await GET list of groups; var id = groups.First(g => g.Name == "Admins").Id;
await client.PostAsync($"/groups/{id}/users", body);
Defensive patterns

Strategy: try-catch

Validate before calling

var exists = (await api.SearchGroups(name)).Any(g => g.Id == groupId);
if (!exists) throw new InvalidOperationException($"Group {groupId} not found in tenant");

Type guard

bool IsValidGroup(GroupDto? g) => g is not null && g.Id != Guid.Empty;

Try / catch

try { await api.AddUsersToGroup(groupId, userIds); }
catch (ApiException e) when (e.Status == 404) { logger.LogWarning("Group {GroupId} not found", groupId); }

Prevention

When it happens

Trigger: 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).

Common situations: 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.

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

Appendix: source

Thrown at src/Modules/Identity/Modules.Identity/Features/v1/Groups/AddUsersToGroup/AddUsersToGroupCommandHandler.cs:35

    public AddUsersToGroupCommandHandler(IdentityDbContext dbContext, ICurrentUser currentUser, IUserPermissionService userPermissionService)
    {
        _dbContext = dbContext;
        _currentUser = currentUser;
        _userPermissionService = userPermissionService;
    }

    public async ValueTask<AddUsersToGroupResponse> Handle(AddUsersToGroupCommand command, CancellationToken cancellationToken)
    {
        ArgumentNullException.ThrowIfNull(command);

        // Validate group exists
        var groupExists = await _dbContext.Groups
            .AnyAsync(g => g.Id == command.GroupId, cancellationToken);

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

        // Validate user IDs exist
        var existingUserIds = await _dbContext.Users
            .Where(u => command.UserIds.Contains(u.Id))
            .Select(u => u.Id)
            .ToListAsync(cancellationToken);

        var invalidUserIds = command.UserIds.Except(existingUserIds).ToList();
        if (invalidUserIds.Count > 0)
        {
            throw new NotFoundException($"Users not found: {string.Join(", ", invalidUserIds)}");
        }

        // Get existing memberships
        var existingMemberships = await _dbContext.UserGroups
            .Where(ug => ug.GroupId == command.GroupId && command.UserIds.Contains(ug.UserId))
            .Select(ug => ug.UserId)

View on GitHub (pinned to 3f2959e683)