SIGN IN SIGN UP

fix(replay): keep playback alive when a hover target is not an element (#4451)

* fix(rrweb): guard hoverElements against non-element hover targets

A mouse event can resolve to a non-element node (text/comment) or a node
detached from the replay document. In those cases getRootNode() returns
the node itself rather than a Document or ShadowRoot, and the next hover
tick calls querySelectorAll('.\:hover') on it, throwing an unhandled
TypeError that stops playback dead.

Skip the hover for non-element targets in moveAndHover, and only cache
lastHoveredRootNode when getRootNode() is actually a Document or
ShadowRoot (clearing it otherwise).

Generated-By: PostHog Code
Task-Id: b9f5d73d-0c68-474d-8d35-58d1a5849317

* chore: add changeset for rrweb hover fix

Generated-By: PostHog Code
Task-Id: b9f5d73d-0c68-474d-8d35-58d1a5849317

* fix(changeset): target posthog-js instead of @posthog/rrweb

Per AGENTS.md:189, changesets must not target modules under packages/rrweb/;
they ship bundled inside posthog-js. The @posthog/rrweb* packages are also
deliberately excluded from the publish matrix in .github/workflows/release.yml,
so a @posthog/rrweb bump publishes nothing and the fix never reaches users.
Retarget the changeset to posthog-js (patch), keeping the same description.

Generated-By: PostHog Desktop
Task-Id: 8c090f5c-ab25-4791-bfa8-71fae04282c3

* fix(rrweb): restore hover handling for non-element hover targets

The earlier crash fix gated moveAndHover on ELEMENT_NODE, which over-corrected:
it also skipped removing the previous :hover classes and hovering the target's
nearest ancestor element, a cosmetic replay-fidelity regression for text/comment
targets that used to work pre-fix.

hoverElements is already crash-safe for any node kind (it only caches a root
node when getRootNode() is actually a Document/ShadowRoot), so pass the target
straight through again. Widen hoverElements to accept Node and start the :hover
climb from the nearest ancestor element, so non-element targets still clear the
stale :hover state and hover their parent chain, while detached nodes stay safe.

Generated-By: PostHog Desktop
Task-Id: 8c090f5c-ab25-4791-bfa8-71fae04282c3

* test(rrweb): cover repeated hover on a detached non-element node

Also trims the explanatory comments to one line each.

---------

Co-authored-by: posthog[bot] <206114724+posthog[bot]@users.noreply.github.com>
Co-authored-by: Tue Haulund <tue@posthog.com>
P
posthog[bot] committed
e1d993c6ffa38b7fc8d622148ae0479fbdf1e210
Parent: ab5c30c
Committed by GitHub <noreply@github.com> on 8/21/2026, 1:37:39 PM