Skip to content

fix(react-lang): stop ElementErrorBoundary from crashing the host with a commit-phase insertBefore error#744

Open
serhiizghama wants to merge 2 commits into
thesysdev:mainfrom
serhiizghama:fix/error-boundary-no-stale-children
Open

fix(react-lang): stop ElementErrorBoundary from crashing the host with a commit-phase insertBefore error#744
serhiizghama wants to merge 2 commits into
thesysdev:mainfrom
serhiizghama:fix/error-boundary-no-stale-children

Conversation

@serhiizghama

Copy link
Copy Markdown

Closes #727.

ElementErrorBoundary catches a render error and then returns this.lastValidChildren — element instances captured from an earlier render. React has already reconciled and moved the DOM for those elements, so re-inserting them desyncs the fiber tree from the live DOM and throws NotFoundError: Failed to execute 'insertBefore' on 'Node' in the commit phase. Because it's a mutation-phase error it can't be caught by a nested boundary — it escalates to the app root and unmounts the whole subtree. It shows up in streaming chat UIs and whenever a sibling re-render forces an already-rendered Renderer subtree to re-render.

The fix is to render null on error rather than re-presenting the stale children. The boundary still auto-recovers as soon as new valid children arrive (the existing componentDidUpdate reset), so a transient streaming error clears on the next update instead of crashing. This matches the workaround the reporter verified. The trade-off is losing the "show last good state" for the one frame an element is broken, which seems well worth not tearing down the app — but happy to reconsider if you'd rather keep last-good-state via a keyed remount instead.

The package had no test setup, so I added a jsdom vitest config and a regression test driving the boundary through error → recovery: it asserts the boundary renders nothing after a child throws (not the stale subtree) and recovers when valid children return. Confirmed it fails against the old return this.lastValidChildren. typecheck/eslint/prettier clean.

…ldren

The ElementErrorBoundary re-presented the previously rendered children
on error (this.lastValidChildren). Those are element instances from an
earlier render whose DOM React has already reconciled/moved, so
re-inserting them desyncs the fiber tree from the live DOM and throws an
uncatchable insertBefore error in React's commit phase, unmounting the
whole subtree. Return null on error instead; the boundary still
auto-recovers when new valid children arrive.
@vishxrad vishxrad requested a review from abhithesys July 9, 2026 06:08
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.

Renderer: commit-phase insertBefore NotFoundError from ElementErrorBoundary re-presenting stale children (+ index-keyed children)

1 participant