core: Suspense+KeepAlive+AsyncComponent+v-if causes the `Uncaught (in promise): Cannot read properties of null (reading 'parentNode')`

Vue version

3.2.37

Link to minimal reproduction

https://play.vuejs.org/#eNqNVMtu2zAQ/JWFLpGBWEyRnlLZiBvk0BZtg9pHXRRpZTGVSIKk/EDgf++SlGzVToCcLHJfM7NDv0YLpZJNh9FdlFpsVZNbnGcCIF12RqEw4UTnkm/6Tzr8QFSLhm+GqL98aNXC7EUBmymvZlnEzbKWW5FFwE6V7Lw0ZUPnlI1mpmwEJzWF5sqCQdspn8tbJbWF19CjxIoL9MMfJEUECnsdQlL8lJ2wWPZnjZX/OkClZQtXxP3qy6gjkegjCXO9nDguwaUUUhifEWjO3pwbhznxBGZzELiFJ+rGDcaxRuMve9Dg6Kx4i7KzcUinjJjaT67h083NzcTjIqgT9+tOJxC9toSBCMVWdzjEj4T7nv20i1lHFIwBr1z82NRKcB3B1igAN6j3tuZiDVveNPCM4EiPqqWGzqDf/xw4ocO8BFmdDHHcfj8g2eQNtZ9BlTcGB5aedOB8cD8pC1ufR9dRWM60zVXyYqQgt3r45DEfMFl0NxDKItqYO2dRba0yd4wVpaCyEsl1OhFomVAtu6c0pkkpUmVayvb+NrlNPpMZjR1fJ2ja6bOWW4OammRR7yM/htElyTPVKErUqD869qxsPPosdDHey5OJA4ky2PPy7Z7e6qrmBizu6O3UsmtKciS1d0ukaVSxxzI8vVAyenU0wBoyW8XXZ5oXNJc3qH8ry8mM/2mfN43cfvd3zkJHsYoai79v3L+YXRDtibzvqI8Etrleow3hx+UvIjEKtrLsmn7P7wT/oJFN5zCGtK+dKAn2KM+j/eYtRP5emcedpb+fgZQD6uX2+X7hTvL3qJ/g0jqPazr8AxfWwHU=

Steps to reproduce

The reproduction link demonstrates the issue with no action required.

  1. Put an async component inside the <KeepAlive>.
  2. Assume we have <Suspense> somewhere up in the tree.
  3. Add conditional rendering to that async component using v-if. The initial condition should be set to true.
  4. Change that condition to the false before the async component is fully loaded.

What is expected?

The async component is loaded but not rendered. No errors in the logs.

What is actually happening?

[Vue warn]: Unhandled error during execution of scheduler flush. This is likely a Vue internals bug. Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/core 
  at <KeepAlive> 
  at <Repl>

vue.runtime.esm-browser.js:9243 Uncaught (in promise) TypeError: Cannot read properties of null (reading 'parentNode')
    at parentNode (vue.runtime.esm-browser.js:9243:30)
    at ReactiveEffect.componentUpdateFn [as fn] (vue.runtime.esm-browser.js:7062:17)
    at ReactiveEffect.run (vue.runtime.esm-browser.js:531:25)
    at instance.update (vue.runtime.esm-browser.js:7094:56)
    at updateComponent (vue.runtime.esm-browser.js:6919:26)
    at processComponent (vue.runtime.esm-browser.js:6852:13)
    at patch (vue.runtime.esm-browser.js:6450:21)
    at patchBlockChildren (vue.runtime.esm-browser.js:6756:13)
    at patchElement (vue.runtime.esm-browser.js:6664:13)
    at processElement (vue.runtime.esm-browser.js:6530:13)

Notes

Another issue here is Uncaught (in promise): suspense.resolve() is called without a pending branch. error that is thrown if there is no KeepAlive component in the tree. This error is caused by double calling the “resolve” method of the same suspense object when an async component is unmounted before the resolution of the suspense.

https://github.com/vuejs/core/blob/3be4e3cbe34b394096210897c1be8deeb6d748d8/packages/runtime-core/src/renderer.ts#L2274-L2290

https://github.com/vuejs/core/blob/3be4e3cbe34b394096210897c1be8deeb6d748d8/packages/runtime-core/src/components/Suspense.ts#L224-L226

You can put an async component into a wrapper component (it can just render the default slot). In that case neither KeepAlive or Suspense is rerendered. Although this makes KeepAlive useless.

https://play.vuejs.org/#eNqNVE1P4zAQ/Suj7GFTicZ0uye2rWARh/1GC8dcQjIhhsS2bKcFof73HdtJmhSQ9pSM5/O9efZLdKFUsm0xOotWFhtVZxY3qQBY3bRGoTDBIrvg2+6XjB+I6qLm297rDy8btRjZ4eTCPIsctnNertOIm5tK7kQaARsnsknmih1XX7FD82FK+FBmdX2X5Y9D5k+ZFVzcJ0nS500hsRGmiW9lcs2VBYO2VT6WN0pqCy+hUIElF+ihXEryCBT2JLik+CVbYbHobI2l/9tDqWUDH4nbj19GFQlq50mYq+XIPw5YTCIWfYgLyqUwPibwun5ztDiMEs9gvQGBO7imctxgHGs0/rDDBQ7xLW9QtjYO4RQRU/nZCSxOT09nfjJCM3NfZx2G6JZJMxDm2OoWe//ASVez6/aq1zAFY8BL5x+KWgmuItgKBeAW9bOtaLWw43UNdwgO9ChbamgNesFtgNN0mBUgy4MCB410DZJtVlP5NZCIDPYoPeiAee8+KxaEsYlOorCeeZOp5MFIQRfGj0+i9g6TRmc9oDSijTk7jSprlTljLC8EpRVIqtaJQMuEatg5hTFNTBEr80I258vkU7L8TGo3dnyeoGnmd1ruDGqqkkad1nwfRofEz1yjKFCj/t++R2mT3ke+V/09QanYEy29hl8/IIc7e1txAxaf6IJVsq0L0iSVd2ukbpTxjEW4nyFldDWpgTUkt5LfH7GeU19eo/6jLCc5Ttind0HuvvszJ6KBrbzC/PGN8wfzFFi7JvU76COGbabv0Qb31c1vAjFyNrJo627T7zj/opF162YMYV9bUdDYozg/7TcvIlL4rbl6svRG9aDcoJ5uH+837ih/D/ph3GWyPFqTf0ime9Ked1NL615kssbc7/8Bq7z4Vg==

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 16
  • Comments: 16 (5 by maintainers)

Commits related to this issue

Most upvoted comments

this is serious issue - is it on the roadmap?

Same issue for me with Nuxt 3.1.1.

Changing line 35 of @vue/runtime-dom runtime-dom.esm-bundler.js to parentNode: node => node ? node.parentNode : null, seems to fix the issue though I am not sure what downstream effects this could have.

I have same issue, so only this answer helped me. Hope it will be fixed soon

Same issue for me with Nuxt 3.1.1.

Changing line 35 of @vue/runtime-dom runtime-dom.esm-bundler.js to parentNode: node => node ? node.parentNode : null, seems to fix the issue though I am not sure what downstream effects this could have.