core icon indicating copy to clipboard operation
core copied to clipboard

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

Open mefcorvi opened this issue 3 years ago • 2 comments

Vue version

3.2.37 Works fine in 3.2.36

Link to minimal reproduction

https://sfc.vuejs.org/#eNp9U8uK2zAU/ZWLNuNAYqVbjxMIsyl0U5hCN9q48XWjwZaEJDstg/+9elixMjOdQLDu69xzjq1XclKqnEYkFaktDqpvLB6ZAKhbPh0BwJ9d9DwahcLEWsj4egqW8Cv2vazpm8o3RHXq+bTOhvTToGDa8e7ACDfPF3kVjAD1K5dfBkHfY+RranpHL5VqmimqzVlzZUMDH5TUFl7jdIsdF3gyf8X5SbqKQGG3eek+O0On5QAPzrSHxwzN64mVkvoJ72ps8H/8E5ocYDP24ZkDF4lKY5tik4gBaLSjFmvslkWrKrB6xO3Nozke5oX3OQGbah12BKsPxRYrvFt+OILAK3x3UrjBotBoQjIjAWDQ/uADytEWceSuymz0pMit2JT2giLAPa6t+Wv2/OHLfr/fBNuW1GbRBJBOSeUgR2GxzQ37jJe9cFMu/sEBuqY3eFsUN6fFwc7ZRzVdvhuyJVHUbmhU+WKkcFcmoLvvNxQMIze3GXGSfczIxVplKkpNd/Y+vJhS6t/UnUrt6DuyJZph90vLq0HtgBlZ5AUM6pIT6p1G0aJG/Rnmm9Z3uEEUE7OTkt7Kx9c+7v8pdd/+5z6R+R+yrUe9

Steps to reproduce

The reproduction link demonstrates the issue with no action required.

  1. Put an async component inside the <KeepAlive>.
  2. Suppose we have <Suspense> somewhere up in the tree.
  3. Add conditional rendering to that async component using v-if. Initial condition must be true.
  4. Change that condition to the false before the async component is finally 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)

Any additional comments?

It's possible to wrap content of the KeepAlive to other component without v-if (e.g. div) to work this around. In the Vue SFC playground this causes Uncaught (in promise): suspense.resolve() is called without a pending branch. but in our case this actually has worked.

mefcorvi avatar Aug 13 '22 00:08 mefcorvi

Same error, what's the progress?

jiangmaniu avatar Sep 23 '22 09:09 jiangmaniu

在vuepress 2.x下面有同样的问题 image

wellfrog16 avatar Oct 03 '22 02:10 wellfrog16

The reproduction throws the same error on vue v3.2.36

DrJume avatar Feb 17 '23 22:02 DrJume

I had the same issue inside a Nuxt v3.2.2 app, probably caused by a suspense boundary with async components.

In the following line prevTree.el is null, when the error is thrown (null.parentNode). Sometimes it is "", which does not throw, as "".parentNode gives undefined, which does not cause any problems. https://github.com/vuejs/core/blob/a0e7dc334356e9e6ffaa547d29e55b34b9b8a04d/packages/runtime-core/src/renderer.ts#L1496

I think it is some kind of race condition, where the prevTree.el is not available, because of the async component being removed / not being ready.

DrJume avatar Feb 17 '23 22:02 DrJume

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.

joel-wenzel avatar Feb 23 '23 16:02 joel-wenzel

Same issue here.

aKzenT avatar Apr 05 '23 12:04 aKzenT

Same issue on my side :(

theguriev avatar May 02 '23 10:05 theguriev

On 3.3, this can be resolved by using a nested <Suspense suspensible>:

https://play.vuejs.org/#eNp9VLFu2zAQ/ZUDl8iALaZIuyiyESNLgS4FUqALF8U612wlkiApuUGgfw9FihZtJxkE8e7x3r17pPRKtkrlfYekIKXFVjWVxQ0TAGXN+w0AjGsXPXVGoTAB85kRj8EUfsemkSU9Rzz6A1FtG97P9ScoMoMJC/7cIPQrvl8zws3TQR4FI2dlzPrCx1YB3UwCE0J6pTUC1ypSsReFESpp4ktpdpor6zfwVklt4TVU17jnArfmRewepUMECrtMofPsAHstW7hx1t/cJ2zjUAHJ6Vgxnk3YMD74329yhFXX+HdKnEUpla2yRRQGoNF2WsyxaxZ8LcDqDpcnC4ewGCbdu0hsirnYCSzeHTab6V3z9QYEHuGnG4UbzDKNxicTEQAG7S/eouxsFkrOUGaDJ1lqxSK3BxSe7j493LRwWMK329uFd23KLKaRAOIqDtnKTlisU78+k2UP3OSTfbCGfdUYPDVyjb/Mjb2bwxiVdLo2ZEnCTKu2UvlfI4X77jy7u+seMIyczGbETTzGjBysVaagtBPq35/cHQx9cBjVTrtTuqpl+3CX3+Vf3Z01Nk3naNrVs5ZHg9o1ZGQa23NTl+xRrzSKGjXqT3td7E37XUBXPb0RTAxu/HiQ7/9vgrbfUjf1B58gGd4AhbdsBA==

antfu avatar Jun 07 '23 21:06 antfu

Here is another reproduction that does not seemingly make use of KeepAlive but still triggers this error. https://stackblitz.com/edit/github-8d62xc To trigger, click on one of the links.

The code is nonsensical from the practical aspect as it hides the element when it loads the fallback component. Despite this, it is hard for me to assess whether the code itself is valid and belongs to the same type of issue.

Ingramz avatar Jul 03 '23 17:07 Ingramz

On 3.3, this can be resolved by using a nested <Suspense suspensible>:

https://play.vuejs.org/#eNp9VLFu2zAQ/ZUDl8iALaZIuyiyESNLgS4FUqALF8U612wlkiApuUGgfw9FihZtJxkE8e7x3r17pPRKtkrlfYekIKXFVjWVxQ0TAGXN+w0AjGsXPXVGoTAB85kRj8EUfsemkSU9Rzz6A1FtG97P9ScoMoMJC/7cIPQrvl8zws3TQR4FI2dlzPrCx1YB3UwCE0J6pTUC1ypSsReFESpp4ktpdpor6zfwVklt4TVU17jnArfmRewepUMECrtMofPsAHstW7hx1t/cJ2zjUAHJ6Vgxnk3YMD74329yhFXX+HdKnEUpla2yRRQGoNF2WsyxaxZ8LcDqDpcnC4ewGCbdu0hsirnYCSzeHTab6V3z9QYEHuGnG4UbzDKNxicTEQAG7S/eouxsFkrOUGaDJ1lqxSK3BxSe7j493LRwWMK329uFd23KLKaRAOIqDtnKTlisU78+k2UP3OSTfbCGfdUYPDVyjb/Mjb2bwxiVdLo2ZEnCTKu2UvlfI4X77jy7u+seMIyczGbETTzGjBysVaagtBPq35/cHQx9cBjVTrtTuqpl+3CX3+Vf3Z01Nk3naNrVs5ZHg9o1ZGQa23NTl+xRrzSKGjXqT3td7E37XUBXPb0RTAxu/HiQ7/9vgrbfUjf1B58gGd4AhbdsBA==

Is this implemented in Nuxt? Maybe @danielroe might be interested for https://github.com/nuxt/nuxt/issues/13309

Rigo-m avatar Jul 31 '23 14:07 Rigo-m

Nuxt 3.7.3

Detailed reproduction: https://stackblitz.com/edit/nuxt-starter-btlcfb?file=pages%2Fwaiting.vue

ilyaDegtyarenko avatar Sep 14 '23 17:09 ilyaDegtyarenko

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.

alexovn avatar Sep 22 '23 16:09 alexovn

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.

Had the same problem in nuxt 3.8.0. Finally solved by patching in this way! Thank you, i hope can be helpful for the fix

plcdnl avatar Oct 20 '23 14:10 plcdnl

this is serious issue - is it on the roadmap?

TomasSestak avatar Oct 27 '23 11:10 TomasSestak

The problem is here: https://github.com/vuejs/core/blob/3be4e3cbe34b394096210897c1be8deeb6d748d8/packages/runtime-core/src/components/Suspense.ts#L211-L244 When the component is toggled before the pending tree is resolved, patching should not be performed. Instead, the logic under the "else" statement should be executed. based on the current code, the component should be used as the root node of Suspense and should not be wrapped by any other elements.

The correct nesting order should be as follows:

<KeepAlive>
  <Suspense>
    <!-- main content -->
    <component :is="Component"></component>

    <!-- loading state -->
    <template #fallback>
      Loading...
    </template>
  </Suspense>
</KeepAlive>

see https://vuejs.org/guide/built-ins/suspense.html#combining-with-other-components

or add a key see

<Suspense>
  <div :key="+isShown">
    <KeepAlive>
      <CmpAsync v-if="isShown" />
    </KeepAlive>
  </div>
</Suspense>

this will be fixed via #7290

edison1105 avatar Oct 29 '23 00:10 edison1105

duplicate of https://github.com/vuejs/core/pull/6095

edison1105 avatar Nov 03 '23 00:11 edison1105