{"record":{"id":"1b9a1361d3560729","repo":"plotly/plotly.js","slug":"fx-hover-failed","errorCode":null,"errorMessage":"Fx.hover failed","messagePattern":"Fx\\.hover failed","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/components/fx/hover.js","lineNumber":480,"sourceCode":"            }\n        }\n\n        evt.pointerX = xpx + xaArray[0]._offset;\n        evt.pointerY = ypx + yaArray[0]._offset;\n\n        if ('xval' in evt) xvalArray = helpers.flat(subplots, evt.xval);\n        else xvalArray = helpers.p2c(xaArray, xpx);\n\n        if ('yval' in evt) yvalArray = helpers.flat(subplots, evt.yval);\n        else yvalArray = helpers.p2c(yaArray, ypx);\n\n        // Save pointer position to gd so that it can be included in all hover/click event data,\n        // even when hoveranywhere and clickanywhere are not enabled\n        gd._hoverPointerX = evt.pointerX;\n        gd._hoverPointerY = evt.pointerY;\n\n        if (!isNumeric(xvalArray[0]) || !isNumeric(yvalArray[0])) {\n            Lib.warn('Fx.hover failed', evt, gd);\n            return dragElement.unhoverRaw(gd, evt);\n        }\n    }\n\n    // Save coordinate values so clickanywhere can be used without hoveranywhere\n    if (fullLayout.clickanywhere) {\n        gd._hoverXVals = xvalArray;\n        gd._hoverYVals = yvalArray;\n        gd._hoverXAxes = xaArray;\n        gd._hoverYAxes = yaArray;\n    }\n\n    // the pixel distance to beat as a matching point\n    // in 'x' or 'y' mode this resets for each trace\n    var distance = Infinity;\n\n    // find the closest point in each trace\n    // this is minimum dx and/or dy, depending on mode","sourceCodeStart":462,"sourceCodeEnd":498,"githubUrl":"https://github.com/plotly/plotly.js/blob/1d090e0b5ffb8d0fdf6e0e4ff51d3f3cf67f1314/src/components/fx/hover.js#L462-L498","documentation":"Fx.hover converts the event's pointer position into axis coordinates (xvalArray/yvalArray). If the resulting first values are not numeric, the library warns 'Fx.hover failed', unregisters the hover, and returns instead of building hover labels. This guards against hover events fired at positions that don't map to the plot's coordinate system.","triggerScenarios":"Dispatching a synthetic mouse event without valid clientX/clientY/pageX/pageY; calling Fx.hover with an event object lacking pointer coordinates; hover triggered on an axis whose conversion yields NaN (e.g. category/NaN data at the pointer, or zero-size plot during transition).","commonSituations":"Simulating hover in tests/automation with {clientX: undefined}; calling Fx.hover during a relayout/resize when the plot has no size yet; framework re-renders firing hover on a detached or hidden (display:none, width 0) graph div.","solutions":["Provide real numeric coordinates on synthetic events: {clientX, clientY, pageX, pageY} computed from the graph div's bounding rect.","Wait for the plot to have nonzero size (await Plotly.newPlot, and check gd.clientWidth) before invoking hover.","Convert your own data coordinates to pixel coordinates first, or use Plotly.Fx.hover with properly formed events only.","Skip hover when the container is hidden/display:none — coordinates cannot map to data.","In tests, use Plotly's internal helpers or full MouseEvent constructors instead of plain objects."],"exampleFix":"// before\nPlotly.Fx.hover(gd, {x: 100, y: 200}); // not real pointer fields\n// after\nconst r = gd.getBoundingClientRect();\nPlotly.Fx.hover(gd, new MouseEvent('mousemove', {\n  clientX: r.left + r.width / 2,\n  clientY: r.top + r.height / 2\n}));","handlingStrategy":"type-guard","validationCode":"function hasPointer(evt) {\n  return evt && Number.isFinite(evt.clientX) && Number.isFinite(evt.clientY) &&\n    Number.isFinite(evt.pointerX) && Number.isFinite(evt.pointerY);\n}\nif (!hasPointer(evt) || gd.clientWidth === 0) return;","typeGuard":"function isHoverableEvent(evt, gd) {\n  return evt instanceof MouseEvent && Number.isFinite(evt.clientX) &&\n    gd instanceof HTMLElement && gd.clientWidth > 0;\n}","tryCatchPattern":"if (!isHoverableEvent(evt, gd)) {\n  console.warn('Fx.hover skipped: no numeric pointer position');\n  return;\n}\nPlotly.Fx.hover(gd, evt, subplotId);","preventionTips":["Construct real MouseEvent instances with clientX/clientY for synthetic hover.","Compute coordinates from gd.getBoundingClientRect().","Never call hover while the graph is display:none or mid-resize.","Await newPlot/relayout before dispatching hover events."],"tags":["hover","event","coordinates"],"backgroundTag":"invalid-pointer-coordinates","analyzedSha":"1d090e0b5ffb8d0fdf6e0e4ff51d3f3cf67f1314","analyzedAt":"2026-09-02T22:03:39.906Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}