{"record":{"id":"1a37d2c467d6d291","repo":"bytebase/bytebase","slug":"failed-to-batch-get-users-by-emails","errorCode":null,"errorMessage":"failed to batch get users by emails","messagePattern":"failed to batch get users by emails","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/api/v1/user_service.go","lineNumber":1593,"sourceCode":"\t\tmembers, _ := s.GetGroupMembersSnapshot(ctx, workspaceID, \"groups/\"+ref)\n\t\tfor member := range members {\n\t\t\tif strings.HasPrefix(member, \"users/\") {\n\t\t\t\temails[strings.ToLower(strings.TrimPrefix(member, \"users/\"))] = struct{}{}\n\t\t\t}\n\t\t}\n\t}\n\tif len(emails) == 0 {\n\t\treturn 0, nil\n\t}\n\temailList := make([]string, 0, len(emails))\n\tfor email := range emails {\n\t\temailList = append(emailList, email)\n\t}\n\t// Pass an empty workspace to look up principals by email only: the seat set is\n\t// already derived from policy, we just need each principal's deleted state.\n\tusers, err := s.BatchGetUsersByEmails(ctx, \"\", emailList)\n\tif err != nil {\n\t\treturn 0, errors.Wrapf(err, \"failed to batch get users by emails\")\n\t}\n\tdeleted := 0\n\tfor _, user := range users {\n\t\tif user.MemberDeleted {\n\t\t\tif _, ok := emails[user.Email]; ok {\n\t\t\t\tdeleted++\n\t\t\t}\n\t\t}\n\t}\n\treturn len(emails) - deleted, nil\n}\n\n// userCountGuard checks seat limits before adding a new IAM member (e.g. SSO login).\n// Uses >= because the new user has not been counted yet.\n// If policy is nil, reads the current workspace IAM policy.\nfunc userCountGuard(ctx context.Context, s *store.Store, licenseService *enterprise.LicenseService, workspaceID string, policy *storepb.IamPolicy, saas bool) error {\n\tif policy == nil {\n\t\tp, err := s.GetWorkspaceIamPolicy(ctx, workspaceID)","sourceCodeStart":1575,"sourceCodeEnd":1611,"githubUrl":"https://github.com/bytebase/bytebase/blob/1870550677fe08f0d2a78c07acd27541464eb945/backend/api/v1/user_service.go#L1575-L1611","documentation":"Wraps a store failure in countUsersInIamPolicy when BatchGetUsersByEmails fails while resolving principals' deleted state for seat counting. Used by server info, password-reset checks, and IAM policy updates; means the seat count could not be computed.","triggerScenarios":"Thrown at backend/api/v1/user_service.go:1593 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Retry the operation","Check metadata DB health"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"1870550677fe08f0d2a78c07acd27541464eb945","analyzedAt":"2026-09-06T21:16:13.665Z","contentChangedAt":"2026-09-06T21:16:13.665Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}