Skip to content

[BUG] Delegated mouseover listener crashes on synthetic events targeting document (dataset is undefined) #1277

Closed

Description

@aramarakelyan88

Bug description

In v6's event-delegation model, the single document-level mouseover listener throws TypeError: Cannot read properties of undefined (reading 'tooltipId') when an event's target is the document itself (not an Element).

This happens with synthetic / untrusted mouseover events, which are commonly dispatched directly on document by browser extensions, password managers, and accessibility/automation tooling. Real user hovers always target an Element, so this stays hidden in normal use but surfaces in production.

The crash is in resolveDataTooltipAnchor (src/utils/resolve-data-tooltip-anchor.ts):

function resolveDataTooltipAnchor(targetElement, tooltipId) {
  let currentElement = targetElement;          // = document
  while (currentElement) {
    if (currentElement.dataset.tooltipId === tooltipId) {  // document.dataset is undefined -> throws
      return currentElement;
    }
    currentElement = currentElement.parentElement;
  }
  return null;
}

document.dataset is undefined (only HTMLElement / SVGElement expose dataset), so reading .tooltipId from it throws.

The guard in resolveAnchorElementRef (src/components/Tooltip/use-tooltip-events.tsx) only checks targetElement?.isConnected, but document.isConnected === true, so document slips through into the data-tooltip-id branch. Note the anchorSelector branch is wrapped in a try/catch, but the dataTooltipId branch is not, so the common data-tooltip-id usage is unprotected.

Package version

6.0.5 (also confirmed in 6.0.0)

To reproduce

  1. Render a tooltip using the default attribute anchor:
    <a data-tooltip-id="my-tip">hover me</a>
    <Tooltip id="my-tip" content="hi" />
  2. Dispatch a synthetic mouseover on the document (this is what extensions/tooling do):
    document.dispatchEvent(new MouseEvent('mouseover', { bubbles: true }));
  3. The delegated listener runs resolveDataTooltipAnchor(document, 'my-tip'), which does document.dataset.tooltipId and throws.

Expected behavior

The delegated mouseover/mouseout/etc. listeners should ignore non-Element targets (such as document) and not throw.

Actual behavior

Uncaught TypeError: Cannot read properties of undefined (reading 'tooltipId')
    at resolveDataTooltipAnchor (resolve-data-tooltip-anchor.ts)
    at resolveAnchorElementRef.current (use-tooltip-events.tsx)
    at handler (use-tooltip-events.tsx)
    at dispatch (event-delegation.ts)

The error escapes to window.onerror.

Suggested fix

Bail on non-Element targets at the guard, and/or harden the walk:

// use-tooltip-events.tsx - resolveAnchorElementRef.current
if (!(targetElement instanceof Element) || !targetElement.isConnected) {
  return null;
}

// and/or resolve-data-tooltip-anchor.ts
while (currentElement) {
  if (currentElement instanceof HTMLElement && currentElement.dataset.tooltipId === tooltipId) {
    return currentElement;
  }
  currentElement = currentElement.parentElement;
}

Environment

  • OS: Windows 10+
  • Browser: Chrome 139
  • React version: 19
  • Framework: Next.js
  • Rendering mode: client

Additional context

Caught via production error monitoring (Sentry): 26 occurrences across 26 unique users over 3 days. The event payload confirms isTrusted: false and target: [object HTMLDocument] on the mouseover event, consistent with a synthetic event dispatched on document rather than a real user hover.

Activity

  1. self-assigned this
    on May 30, 2026
  2. danielbarion commented on Jun 1, 2026

    @danielbarion
    Member

    @aramarakelyan88 can you please check the following beta release and let me know?

    Beta version released with the last commit 🚀

    yarn add react-tooltip@6.0.5-beta.1278.rc.0
    

    or

    npm install react-tooltip@6.0.5-beta.1278.rc.0
    
  3. aramarakelyan88 commented on Jun 2, 2026

    @aramarakelyan88
    Author

    @danielbarion Verified — 6.0.5-beta.1278.rc.0 fixes it. 🎉

    Tested the published artifact in Chrome (React 19) against the repro from the issue description:

    • 6.0.5 (control): each synthetic mouseover/mouseout dispatched on document throws
      Uncaught TypeError: Cannot read properties of undefined (reading 'tooltipId')
    • 6.0.5-beta.1278.rc.0: same events → no errors
    • Regression checks: real hover still opens the tooltip, and synthetic document-targeted
      events dispatched while the tooltip is open also don't throw

    Thanks for the quick turnaround! Looking forward to the stable release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions