{"record":{"id":"dabd165e184b542a","repo":"weaviate/weaviate","slug":"no-roles-to-revoke-w","errorCode":null,"errorMessage":"no roles to revoke: %w","messagePattern":"no roles to revoke: %w","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"warning","filePath":"cluster/raft_rbac_apply_endpoints.go","lineNumber":111,"sourceCode":"\t}\n\treq := cmd.AddRolesForUsersRequest{User: user, Roles: roles, Version: cmd.RBACAssignRevokeLatestCommandPolicyVersion}\n\tsubCommand, err := json.Marshal(&req)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"marshal request: %w\", err)\n\t}\n\tcommand := &cmd.ApplyRequest{\n\t\tType:       cmd.ApplyRequest_TYPE_ADD_ROLES_FOR_USER,\n\t\tSubCommand: subCommand,\n\t}\n\tif _, err := s.Execute(context.Background(), command); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (s *Raft) RevokeRolesForUser(user string, roles ...string) error {\n\tif len(roles) == 0 {\n\t\treturn fmt.Errorf(\"no roles to revoke: %w\", schema.ErrBadRequest)\n\t}\n\treq := cmd.RevokeRolesForUserRequest{User: user, Roles: roles, Version: cmd.RBACAssignRevokeLatestCommandPolicyVersion}\n\tsubCommand, err := json.Marshal(&req)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"marshal request: %w\", err)\n\t}\n\tcommand := &cmd.ApplyRequest{\n\t\tType:       cmd.ApplyRequest_TYPE_REVOKE_ROLES_FOR_USER,\n\t\tSubCommand: subCommand,\n\t}\n\tif _, err := s.Execute(context.Background(), command); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n","sourceCodeStart":93,"sourceCodeEnd":127,"githubUrl":"https://github.com/weaviate/weaviate/blob/75aa4b6d11f8818305aafd4440b4e32794f7ca04/cluster/raft_rbac_apply_endpoints.go#L93-L127","documentation":"RevokeRolesForUser removes roles from a user via RAFT. It refuses an empty roles variadic list, wrapping schema.ErrBadRequest, since revoking nothing is a no-op and would waste a consensus round. Validation happens before marshaling and cluster execution.","triggerScenarios":"Calling Raft.RevokeRolesForUser(user) with zero variadic role arguments — e.g. a REST handler received an empty or missing \"roles\" array.","commonSituations":"A client sends {\"user\":\"alice\",\"roles\":[]}; a script builds the role list by filtering and ends up with nothing; the CLI is invoked without role arguments.","solutions":["Pass at least one role to revoke","Validate the list before calling and short-circuit with a clear message when empty","Check upstream filtering logic isn't stripping all roles"],"exampleFix":"// before\nraft.RevokeRolesForUser(user, toRevoke...)\n// after\nif len(toRevoke) == 0 {\n    return errors.New(\"no roles to revoke: pass at least one role\")\n}\nraft.RevokeRolesForUser(user, toRevoke...)","handlingStrategy":"validation","validationCode":"if len(roles) == 0 {\n    return fmt.Errorf(\"at least one role is required to revoke from user %q\", user)\n}\n_ = raft.RevokeRolesForUser(user, roles...)","typeGuard":null,"tryCatchPattern":"if err := raft.RevokeRolesForUser(user, roles...); err != nil {\n    if errors.Is(err, schema.ErrBadRequest) {\n        return http.StatusBadRequest, \"roles array must contain at least one role\"\n    }\n    return err\n}","preventionTips":["Check filtered role lists are non-empty before issuing the revoke","Make roles a required, non-empty array in client SDKs and CLI args","Treat empty revoke as a caller bug, not a cluster issue"],"tags":["rbac","validation","raft"],"backgroundTag":"missing-required-argument","analyzedSha":"75aa4b6d11f8818305aafd4440b4e32794f7ca04","analyzedAt":"2026-09-04T14:58:20.392Z","contentChangedAt":"2026-09-04T14:58:20.392Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}