svelte: Uncaught (in promise) TypeError: Cannot read property 'removeChild' of null

I couldn’t reproduce the error in the repl and I also can’t post the data since it is confidential. I’ll try to post as much information as possible though.

This is the component:

  {#each schueler as s (s.ID)}
    {#each s.abschnitte.filter(aktJahr) as a (a.ID)}
        <Voffset/>{a.Jahr}
    {/each}
  {/each}

<script>
  import Voffset from './partials/Voffset.html'
  // the file looks like this
  // ./partials/Voffset.html
  // <div></div>

  export let jahr, schueler
  // schueler looks like this just way more complex and about 1MB in size
  // schueler = [{abschnitte: [{Jahr: 2017},{Jahr: 2018}]}, {abschnitte: [{Jahr: 2017},{Jahr: 2018}]}]
  $: aktJahr = a => a.Jahr === jahr
</script>
svelte = new Component({ target: document.querySelector('svelte'), props })

this works just fine.

later on when I change some props I do it like this:

svelte.$set({ jahr: abschnitt.jahr, abschnitt: abschnitt.abschnitt })

sometimes it works, sometimes not. It renders the component but then fails and I can’t change the data again.

This is the error message:

internal.mjs:111 Uncaught (in promise) TypeError: Cannot read property 'removeChild' of null
    at detachNode (VM110 bundle.js:113)
    at Object.destroy [as d] (VM110 bundle.js:1555)
    at destroyBlock (VM110 bundle.js:1006)
    at on_outro (VM110 bundle.js:1012)
    at run (VM110 bundle.js:23)
    at Array.forEach (<anonymous>)
    at run_all (VM110 bundle.js:31)
    at check_outros (VM110 bundle.js:535)
    at Object.update [as p] (VM110 bundle.js:1675)
    at update (VM110 bundle.js:937)

this seems to only happen with two nested loops and the imported component.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 7
  • Comments: 39 (13 by maintainers)

Commits related to this issue

Most upvoted comments

Same issue is happening to me while using Sapper when navigating randomly. Very hard to reproduce but it happens often enough for it to be a problem.

I’ve also seen it happen when some library replaced DOM objects leaving it in a state that svelte is confused about. My temp fix is to change line 130 of node_modules/svelte/internal.mjs to:

function detach(node) {
	if(node.parentNode) {
		node.parentNode.removeChild(node);
	}
}

UPDATE: in the latest version this is located at line 181.

I have also encountered this, but cannot reproduce at the moment. It went usually like this:

  1. Visit /items
  2. Click link to /items/[id]/specific (happens to be a sapper app)
  3. Click link to /items => empty page and console shows: TypeError: Cannot read property 'removeChild' of null
function detach(node) {
	if(node.parentNode) {
		node.parentNode.removeChild(node);
	}
}

This answer is the only fix, that worked for me. I’m using Svelte 3.20.1

I’m using a third party library (sortable.js) where items are cloned into a dropzone. From there, they can be deleted again by a button (which removes the DOM node). Each item is a Item.svelte component. Dropzone.svelte is the wrapper.

As soon as i delete an item out of the dropzone and try to change the route, the parentNode.removeChild error appears in the console.

I also tried to add an additional wrapper within Item.svelte and just delete its content, rather than the node itself. This would work as well, but it causes side effects with the third party library and would require additional logic.

So, what is the point of not checking if there is a parentNode in any case in the internal/index.mjs file? Feels kinda unsafe to change a file in the node modules.

I am still having this issue.

I’m still facing this issue:

"devDependencies": {
    "@rollup/plugin-alias": "^2.2.0",
    "dotenv": "^8.2.0",
    "node-sass": "^4.13.0",
    "rollup": "^1.26.3",
    "rollup-plugin-commonjs": "^10.0.0",
    "rollup-plugin-livereload": "^1.0.0",
    "rollup-plugin-multi-entry": "^2.1.0",
    "rollup-plugin-node-resolve": "^5.2.0",
    "rollup-plugin-postcss": "^2.0.3",
    "rollup-plugin-replace": "^2.2.0",
    "rollup-plugin-svelte": "^5.0.3",
    "rollup-plugin-terser": "^5.1.2",
    "sirv-cli": "^0.4.4",
    "svelte": "^3.14.1",
    "svelte-preprocess": "^3.2.6"
  },
index.mjs:147 Uncaught (in promise) TypeError: Cannot read property 'removeChild' of null
    at detach (index.mjs:147)
    at detach_dev (index.mjs:1430)
    at update (index.mjs:637)
    at flush (index.mjs:611)

One very specific block of code that’s causing this issue is this very simple if statement in my code:

{#if $someStore}
    <i class="fas fa-angle-right" aria-hidden="true"></i>
{:else}
    <i class="fas fa-angle-down" aria-hidden="true"></i>
{/if}

Removing this piece of code fixes the issue for me, But I cannot figure out why this is happening, the error triggers whenever there’s an update to the store or any other reactive value.

@InstanceOfMichael I can’t comment on your specific use case but my issue is no longer reproducible against version 3.13.0-alpha.17 after confirming the patch is no longer in place e.g.

function detach(node) {
    node.parentNode.removeChild(node);
}

I am actually not sure if anything changed within Svelte or just reworking my code resolved the issue (I was previously not using a unique enough key within my {#each…})

I appreciate this probably doesn’t help you but thought I would provide an update.

I’m still having this issue. Unfortunately, I could not find a way to replicate the issue on the REPL, so here it is in a repo: https://gitlab.com/tohlenforst/issue2086

git clone https://gitlab.com/tohlenforst/issue2086
npm i
npm run dev

Then just click on a link and then try to click a different link.

REPRODUCTION here: https://codesandbox.io/s/epic-stonebraker-9cxhu

  • open browser’s console
  • click on button “Add random team”
  • wait 3 seconds
  • error in console

Fix by using an intermediate component:

  • open file “Desks.svelte”
  • uncomment on line 12
  • comment on lines from 15 to 23
  • repeat steps from above
  • voilà! it works with no errors!

I tried both with Svelte 3.5.4 and 3.6.5.

// first load — remove SSR'd <head> contents
const start = document.querySelector('#sapper-head-start');
const end = document.querySelector('#sapper-head-end');

if (start && end) {
  while (start.nextSibling !== end) detach(start.nextSibling);
  detach(start);
  detach(end);
}

node.nextSibling -

A Node object, representing the next sibling of the node, or null if there is no next sibling

I get error on first load, the detach calls from code above.

Bug when I add description into head.

<svelte:head>
  <title>test</title>
  <description>test</description>
</svelte:head>

My bad, I’ve added description instead meta tag. Should be

<svelte:head>
  <title>test</title>
  <meta name="description" content="Free Web tutorials">
</svelte:head>

I was having the same exact issue while working with <svelte:component> used alongside <svelte:window on:hashchange>. It was working fine until the components I was loading dynamically were using katex. The fix mentioned by @ciri worked. Currently I’m using patch-package on npm to apply the patch until it is fixed.

Can reproduce this error on demand. Using: “rollup”: “^1.21.2”, “rollup-plugin-commonjs”: “^10.0.0”, “rollup-plugin-livereload”: “^1.0.0”, “rollup-plugin-node-resolve”: “^5.2.0”, “rollup-plugin-postcss”: “^2.0.3”, “rollup-plugin-scss”: “^1.0.2”, “rollup-plugin-svelte”: “^5.0.3”, “rollup-plugin-terser”: “^4.0.4”, “svelte”: “^3.12.0”, “svelte-material-ui”: “^1.0.0-beta.14”, “svelte-routing”: “^1.4.0”

svelte-material-ui has a component call ‘snackbar’. This component is modal and has child nodes. Using this component and then existing the current page (moving to another) provokes this error.

Updating line 145 of ‘node_modules/svelte/internal/index.mjs’ to function detach(node) { if(node.parentNode) { node.parentNode.removeChild(node); } } steps around the error.

@rwwagner90 I updated another hotfix branch to account for v2.6.5. It’s at btakita/svelte#gh-2086-hotfix

There have been some attempts to fix some of the root causes of calling detach when the DOM element is already detached as seen in https://github.com/sveltejs/svelte/pull/3172. However, it’s not yet merged due to an issue.

I created a pull request to have the if (node.parentNode) conditional added to detach. It was not applied due to the desire to find the root cause of the <meta> tag manifestation of this issue.

However, IMO, having the conditional in the detach function is necessary, because there are other manifestations of this error. For example, if the DOM element in a component is removed from software outside of svelte, detach will have the same error.

I’m not sure where the core team currently stands on this issue & fix(es). IMO, the conditional needs to be added to detach to fix all manifestations of this error. Ontologically, detach, as an api, should be declarative (ensure the node is detached) instead of imperative (detach the node), allowing it to be called multiple times by performing a noop if the node is already detached. This way, it won’t matter if the node is removed from the DOM from outside of svelte.

I’ll keep btakita/svelte#gh-2086-hotfix up to date with the latest release in the meantime.