Skip to content

Remove a Portal element from its own parent - #134

Open
spot-uncountable wants to merge 1 commit into
masterfrom
spot/portal-remove-from-own-parent
Open

spot-uncountable wants to merge 1 commit into
masterfrom
spot/portal-remove-from-own-parent

Conversation

@spot-uncountable

Copy link
Copy Markdown
Collaborator

Description

Portal removed its element from document.querySelector('.Ketcher-root') instead of from the node that actually holds it. The platform embeds more than one editor on a page, so that selector can resolve to another instance's root, and removeChild then throws NotFoundError: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.

The same lookup also makes the removal a silent no-op whenever no .Ketcher-root is in the document, which leaks the element. MicromoleculesEditor detaches its root before its inner React root unmounts, so that is the normal single-editor path.

Reported from production as Sentry UNC-F-9BT (uncountableinc/main MAT-88700). React 19 surfaces the throw to window.onerror, so it now reaches error reporting.

Reproduction

In the Uncountable platform, with the fork build currently pinned (3.6.0-unc53):

  1. Open a chemical drawer and open a toolbar multi-tool dropdown, which mounts the Portal.
  2. Put a second .Ketcher-root in the document ahead of the editor's own root, which is what a second embedded editor does.
  3. Close the dropdown, or unmount the editor.

Both steps 3 throw, with this stack:

NotFoundError: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
    at Portal.removeElementFromDOM
    at Portal.componentWillUnmount
    at safelyCallComponentWillUnmount
    at commitDeletionEffectsOnFiber

With this.element.remove() patched into the served bundle, the same two flows raise no error and the element is detached from its real parent.

Testing

ketcher-autotests/tests/specs/unc-regression/editor-instance.spec.ts gains a case that opens the area-selection dropdown, inserts a second editor root, then selects a tool to close the dropdown, and asserts no page error. The case fails on the current code and passes with this change.

Note: the pre-commit and pre-push hooks could not run in the agent pod. npm ci completed, but lint-staged and run-s are absent and a further npm install was OOM-killed. npx prettier --check on both changed files passes; the rest of the checks are left to CI.

Portal removed its element from document.querySelector('.Ketcher-root').
The platform embeds more than one editor on a page, so that selector can
resolve to another instance's root, and removeChild then throws
NotFoundError: The node to be removed is not a child of this node.

Co-Authored-By: Claude Opus 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.

2 participants