diff --git a/src/traces/scattergl/hover.js b/src/traces/scattergl/hover.js
index adb37227089..c6735dfacdd 100644
--- a/src/traces/scattergl/hover.js
+++ b/src/traces/scattergl/hover.js
@@ -43,9 +43,9 @@ function hoverPoints(pointData, xval, yval, hovermode) {
                 Math.max(xl, xr), Math.max(yl, yr)
             );
         }
-    } else if(stash.ids) {
+    } else {
         ids = stash.ids;
-    } else return [pointData];
+    }
 
     // pick the id closest to the point
     // note that point possibly may not be found
@@ -84,9 +84,7 @@ function hoverPoints(pointData, xval, yval, hovermode) {
 
     if(id === undefined) return [pointData];
 
-    calcHover(pointData, x, y, trace);
-
-    return [pointData];
+    return [calcHover(pointData, x, y, trace)];
 }
 
 function calcHover(pointData, x, y, trace) {
@@ -163,7 +161,7 @@ function calcHover(pointData, x, y, trace) {
     var fakeCd = {};
     fakeCd[pointData.index] = di;
 
-    Lib.extendFlat(pointData, {
+    var pointData2 = Lib.extendFlat({}, pointData, {
         color: getTraceColor(trace, di),
 
         x0: xp - rad,
@@ -181,14 +179,14 @@ function calcHover(pointData, x, y, trace) {
         hovertemplate: di.ht
     });
 
-    if(di.htx) pointData.text = di.htx;
-    else if(di.tx) pointData.text = di.tx;
-    else if(trace.text) pointData.text = trace.text;
+    if(di.htx) pointData2.text = di.htx;
+    else if(di.tx) pointData2.text = di.tx;
+    else if(trace.text) pointData2.text = trace.text;
 
-    Lib.fillText(di, trace, pointData);
-    Registry.getComponentMethod('errorbars', 'hoverInfo')(di, trace, pointData);
+    Lib.fillText(di, trace, pointData2);
+    Registry.getComponentMethod('errorbars', 'hoverInfo')(di, trace, pointData2);
 
-    return pointData;
+    return pointData2;
 }
 
 module.exports = {
diff --git a/src/traces/splom/hover.js b/src/traces/splom/hover.js
index f5e9d913588..c5766f2fc87 100644
--- a/src/traces/splom/hover.js
+++ b/src/traces/splom/hover.js
@@ -51,9 +51,7 @@ function hoverPoints(pointData, xval, yval) {
 
     if(id === undefined) return [pointData];
 
-    calcHover(pointData, x, y, trace);
-
-    return [pointData];
+    return [calcHover(pointData, x, y, trace)];
 }
 
 module.exports = {
diff --git a/test/jasmine/tests/gl2d_click_test.js b/test/jasmine/tests/gl2d_click_test.js
index 792436c0f26..20d3fa33b75 100644
--- a/test/jasmine/tests/gl2d_click_test.js
+++ b/test/jasmine/tests/gl2d_click_test.js
@@ -346,6 +346,36 @@ describe('Test hover and click interactions', function() {
         .then(done);
     });
 
+    it('@gl should not error when scattergl trace has missing points', function(done) {
+        var _mock = {
+            data: [{
+                type: 'scattergl',
+                mode: 'markers',
+                x: [1, 2, 3, 4],
+                y: [10, 15, null, 17],
+            }],
+            layout: {
+                width: 500,
+                height: 500
+            }
+        };
+
+        Plotly.plot(gd, _mock)
+        .then(function() {
+            gd.on('plotly_hover', function() {
+                fail('should not trigger plotly_hover event');
+            });
+        })
+        .then(function() {
+            var xp = 300;
+            var yp = 250;
+            var interval = setInterval(function() { hover(xp--, yp--); }, 10);
+            return delay(100)().then(function() { clearInterval(interval); });
+        })
+        .catch(failTest)
+        .then(done);
+    });
+
     it('@gl should show last point data for overlapped scattergl points with hovermode set to closest', function(done) {
         var _mock = Lib.extendDeep({}, mock1);
         _mock.data[0].hovertext = 'text';