snabbdom: Snabbdom tries to remove a node that is already detached, throws exception

Changing the content of an element from an array of children to some innerHTML content currently produces the following exception:

Uncaught DOMException: Node.removeChild: The node to be removed is not a child of this node

This bug can be reproduced as such:

var patch = snabbdom.init([
  snabbdom.propsModule
]);

var el = document.createElement('div');
document.body.appendChild(el);

var vdom = patch(el, snabbdom.h('p', {}, ["Text"]));
patch(vdom, snabbdom.h('p', {props: {innerHTML: "Eh?"}}, []));

In other words:

  • Snabbdom renders an element with TextNode children
  • Snabbdom reuses the element for a new vnode that has no children, but instead sets innerHTML
  • Snabbdom calls on the properties module to update the node first, causing it to set innerHTML
  • Snabbdom attempts to remove the old TextNode from the DOM
  • The TextNode is no longer attached to the DOM; Snabbdom encounters an exception

It can happen when trying to remove elements as well:

var vdom = patch(el, snabbdom.h('p', {}, [snabbdom.h('span', {}, ['LUL'])]));
patch(vdom, snabbdom.h('p', {props: {innerHTML: "Eh?"}}, []));

This time it fails in a different place.


I could provide a PR, but I’m not sure what the preferred fix is. It seems to me that the way Snabbdom allows its modules to “do anything” to a node is somewhat at odds with its assumptions that all DOM operations are safe. My suggestion for a fix is to ensure that the node being removed in DOMAPI.removeChild is still attached to the DOM (in the position expected by Snabbdom), before attempting to remove it:

function removeChild(node: Node, child: Node): void {
  if (child.parentNode === node) {
    node.removeChild(child);
  }
}

I’m not intimately familiar with the implementation or guiding principles in it, so this may not be your preferred solution.

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Reactions: 4
  • Comments: 26 (10 by maintainers)

Commits related to this issue

Most upvoted comments

I’ve been using my down-time to make little Snabbdom PRs and resolve various issues. Because there are many opened issues and PRs, I did not read this great discussion until tonight. @cjohansen it is enjoyable to read your clear input and analysis in all issues and particularly this one.

It seems dumdom continues to be developed and to use Snabbdom despite annoying issues you found and carefully reported which were never resolved,

Would you tell, from a high-level, what is your view of Snabbdom at this time? Has Snabbdom been a good vdom package for you, despite above listed issues? Have you encountered slowness issues like the ones described by @aranchelk? How do you think Snabbdom compares with Inferno and react-dom at this time? Are innerHTML issues the most serious short-coming with Snabbdom? (nice suggestion to support legacy and new core innerHTML implementations)

Also, sharing these recent PRs which might resolve some issues you reported,