Skip to content

fix(rrweb-snapshot): omit srcdoc attribute when rebuilding iframe elements - #1905

Open
yashrao2607 wants to merge 2 commits into
rrweb-io:mainfrom
yashrao2607:fix/1736-iframe-srcdoc-insertBefore
Open

fix(rrweb-snapshot): omit srcdoc attribute when rebuilding iframe elements#1905
yashrao2607 wants to merge 2 commits into
rrweb-io:mainfrom
yashrao2607:fix/1736-iframe-srcdoc-insertBefore

Conversation

@yashrao2607

Copy link
Copy Markdown

Summary

When rebuilding a serialized <iframe> that has a srcdoc attribute, buildNode was setting srcdoc on the live element via node.setAttribute(name, value.toString()) like any other attribute. Setting srcdoc makes the browser asynchronously parse and load its own document into the iframe's contentDocument — but rrweb also separately reconstructs that iframe's document from its own recorded child nodes/mutations (attachDocumentToIframe / the mirror). These two reconstructions race, and the browser's native srcdoc load can clobber (or be clobbered by) rrweb's own tree, desyncing the mirror from the live DOM. A later mutation then targets a node that no longer exists, throwing e.g.:

Failed to execute 'insertBefore' on 'Node': parameter 1 is not of type 'Node'.

...which crashes the replayer (per the report, wrapping it in try/catch just breaks the player instead).

rrdom's diff-based renderer already special-cases this exact issue (see packages/rrdom/src/diff.ts:354 and its CHANGELOG: "Omit the 'srcdoc' attribute of iframes to avoid overwriting content"), but the plain browser-DOM rebuild path in rrweb-snapshot (used by the default web replayer) never got the same treatment. This PR applies the same fix there: skip setting srcdoc, since rrweb's own reconstruction is the source of truth for the iframe's contents.

Test plan

  • Added a test in rebuild.test.ts that builds an <iframe srcdoc="..."> node via buildNodeWithSN and asserts the resulting live element has no srcdoc attribute. Verified it fails without the fix and passes with it.
  • Full rrweb-snapshot test suite (rebuild.test.ts, css.test.ts, snapshot.test.ts) passes: 72/72.
  • tsc -noEmit clean.

Fixes #1736

Setting `srcdoc` on a live iframe makes the browser asynchronously
parse and load its own document into the iframe's contentDocument,
racing against rrweb's own reconstruction of that iframe's document
(built separately from recorded child nodes/mutations). The race can
desync the mirror from the live DOM, so a later mutation ends up
targeting a node that no longer exists, throwing e.g. "Failed to
execute 'insertBefore' on 'Node': parameter 1 is not of type 'Node'"
and taking down the replayer.

rrdom's diff-based renderer already special-cases this (see
packages/rrdom/src/diff.ts and its CHANGELOG), but the plain
browser-DOM rebuild path in rrweb-snapshot did not.

Fixes rrweb-io#1736
@changeset-bot

changeset-bot Bot commented Jul 17, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: fc59324

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 22 packages
Name Type
rrweb-snapshot Patch
rrweb Patch
rrdom Patch
rrdom-nodejs Patch
rrweb-player Patch
@rrweb/all Patch
@rrweb/replay Patch
@rrweb/record Patch
@rrweb/types Patch
@rrweb/packer Patch
@rrweb/utils Patch
@rrweb/browser-client Patch
@rrweb/web-extension Patch
rrvideo Patch
@rrweb/rrweb-plugin-console-record Patch
@rrweb/rrweb-plugin-console-replay Patch
@rrweb/rrweb-plugin-sequential-id-record Patch
@rrweb/rrweb-plugin-sequential-id-replay Patch
@rrweb/rrweb-plugin-canvas-webrtc-record Patch
@rrweb/rrweb-plugin-canvas-webrtc-replay Patch
@rrweb/rrweb-plugin-network-record Patch
@rrweb/rrweb-plugin-network-replay Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: iframe with srcdoc throwing error TypeError: Failed to execute 'insertBefore' on 'Node': parameter 1 is not of type 'Node'.

1 participant