plotly/plotly.js · warning

Fx.hover failed

Error message

Fx.hover failed

What it means

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.

Source

Thrown at src/components/fx/hover.js:480

            }
        }

        evt.pointerX = xpx + xaArray[0]._offset;
        evt.pointerY = ypx + yaArray[0]._offset;

        if ('xval' in evt) xvalArray = helpers.flat(subplots, evt.xval);
        else xvalArray = helpers.p2c(xaArray, xpx);

        if ('yval' in evt) yvalArray = helpers.flat(subplots, evt.yval);
        else yvalArray = helpers.p2c(yaArray, ypx);

        // Save pointer position to gd so that it can be included in all hover/click event data,
        // even when hoveranywhere and clickanywhere are not enabled
        gd._hoverPointerX = evt.pointerX;
        gd._hoverPointerY = evt.pointerY;

        if (!isNumeric(xvalArray[0]) || !isNumeric(yvalArray[0])) {
            Lib.warn('Fx.hover failed', evt, gd);
            return dragElement.unhoverRaw(gd, evt);
        }
    }

    // Save coordinate values so clickanywhere can be used without hoveranywhere
    if (fullLayout.clickanywhere) {
        gd._hoverXVals = xvalArray;
        gd._hoverYVals = yvalArray;
        gd._hoverXAxes = xaArray;
        gd._hoverYAxes = yaArray;
    }

    // the pixel distance to beat as a matching point
    // in 'x' or 'y' mode this resets for each trace
    var distance = Infinity;

    // find the closest point in each trace
    // this is minimum dx and/or dy, depending on mode

View on GitHub (pinned to 1d090e0b5f)

Solutions

  1. Provide real numeric coordinates on synthetic events: {clientX, clientY, pageX, pageY} computed from the graph div's bounding rect.
  2. Wait for the plot to have nonzero size (await Plotly.newPlot, and check gd.clientWidth) before invoking hover.
  3. Convert your own data coordinates to pixel coordinates first, or use Plotly.Fx.hover with properly formed events only.
  4. Skip hover when the container is hidden/display:none — coordinates cannot map to data.
  5. In tests, use Plotly's internal helpers or full MouseEvent constructors instead of plain objects.

Example fix

// before
Plotly.Fx.hover(gd, {x: 100, y: 200}); // not real pointer fields
// after
const r = gd.getBoundingClientRect();
Plotly.Fx.hover(gd, new MouseEvent('mousemove', {
  clientX: r.left + r.width / 2,
  clientY: r.top + r.height / 2
}));
Defensive patterns

Strategy: type-guard

Validate before calling

function hasPointer(evt) {
  return evt && Number.isFinite(evt.clientX) && Number.isFinite(evt.clientY) &&
    Number.isFinite(evt.pointerX) && Number.isFinite(evt.pointerY);
}
if (!hasPointer(evt) || gd.clientWidth === 0) return;

Type guard

function isHoverableEvent(evt, gd) {
  return evt instanceof MouseEvent && Number.isFinite(evt.clientX) &&
    gd instanceof HTMLElement && gd.clientWidth > 0;
}

Try / catch

if (!isHoverableEvent(evt, gd)) {
  console.warn('Fx.hover skipped: no numeric pointer position');
  return;
}
Plotly.Fx.hover(gd, evt, subplotId);

Prevention

When it happens

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

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

Related errors


AI-assisted analysis of plotly/plotly.js@1d090e0b5f (2026-09-02). Data as JSON: /api/errors/1b9a1361d3560729. Report an issue: GitHub.