react-google-maps-api
react-google-maps-api copied to clipboard
IntersectionObserver.observe(undefined) crash when using GoogleMap with floating-ui overlays
Environment
- @react-google-maps/api version: latest (^3.x or ^2.x)
- React version: 18.x
- Browser: Chrome 142
- Build tool: Vite
- Overlay library: floating-ui / Radix (for tooltips/popovers around Google Map)
Description
When integrating @react-google-maps/api with floating-ui / Radix-based overlays in the same component tree, a runtime error occurs:
Failed to execute 'observe' on 'IntersectionObserver': parameter 1 is not of type 'Element'
This error is triggered during the mount of the GoogleMap component, specifically when the positioning logic (Popper/Radix/floating-ui) attempts to observe an element for layout calculations, but passes undefined instead of a valid DOM Element to IntersectionObserver.observe().
Root Cause
The error originates from the intersection observer logic used by floating-ui / Radix for positioning calculations. During GoogleMap initialization, a race condition or timing issue causes the observer to be called with a null or undefined target, instead of a valid Element reference.
Stack Trace (Abbreviated)
IntersectionObserver.observe called with invalid target: undefined
at proto.observe (main.tsx:40)
at y (main.js:253)
at _.xr (main.js:253)
at (anonymous) (@react-google-maps_api.js:390)
at componentDidMount (@react-google-maps_api.js:410)
at commitLayoutEffectOnFiber (chunk-RPCDYKBN.js:17030)
The error occurs during the componentDidMount hook of the GoogleMap component, originating from floating-ui's positioning update logic.
Console Logs
IntersectionObserver error:
IntersectionObserver.observe called with invalid target: undefined
Google Maps load status:
[Telemetry] MapLoadReport {ts: 1764436519966, key: 'FAKE_KEY_FOR_DEV', status: 'error', message: 'google.maps.Map not a function or partial load'}
This suggests that the Google Maps library may be partially loaded or not fully initialized when the overlay positioning logic tries to observe elements, causing the race condition.
Steps to Reproduce
- Create a React component using
@react-google-maps/apiwith GoogleMap - Wrap the GoogleMap in a floating-ui/Radix-based overlay container (e.g., Popover, Tooltip, or custom Popper)
- Mount the component in development mode
- Observe the browser console:
Failed to execute 'observe' on 'IntersectionObserver'...error appears
Expected Behavior
- GoogleMap should mount without errors
- The overlay positioning system should gracefully handle cases where observer targets are not yet available
- No console errors about invalid IntersectionObserver targets
Actual Behavior
- Error: "Failed to execute 'observe' on 'IntersectionObserver': parameter 1 is not of type 'Element'"
- The error is thrown but doesn't currently crash the page (depending on error boundary setup)
- However, it indicates a bug that could cause issues in production
Suggested Fix
The issue likely needs a fix in how the library handles observer targets during component lifecycle. Proposed solutions:
-
In @react-google-maps/api (if applicable):
- Add a guard check before calling IntersectionObserver methods
- Verify that target elements exist and are valid DOM elements
- Defer observer setup until all elements are mounted
-
In floating-ui / Radix (if the bug originates there):
- Add validation:
if (!target || !(target instanceof Element)) return;before calling observe() - Handle race conditions where refs may not be attached yet during layout calculations
- Add validation:
Workaround
A defensive patch can be applied to IntersectionObserver globally (for dev/debugging):
// Patch IntersectionObserver.prototype.observe to skip invalid targets
const originalObserve = IntersectionObserver.prototype.observe;
IntersectionObserver.prototype.observe = function(target) {
if (!target || !(target instanceof Element)) {
console.warn('[Telemetry] IntersectionObserver.observe called with invalid target:', target);
console.trace();
return; // Skip invalid targets gracefully
}
return originalObserve.call(this, target);
};
This patch protects against the error but masks the root cause—the actual libraries should fix their validation.
Related Issues / PRs
- Likely related to floating-ui or Radix's integration with IntersectionObserver
- May be a known race condition when maps load asynchronously
Additional Context
- This issue was detected in a production-like environment with potential partial library loads (adblock, CSP issues, etc.)
- A telemetry system was implemented to capture these observe() calls for debugging
- The error is reproducible in Vite dev environment and potentially in production builds