svelte
svelte copied to clipboard
New component `root` property may throw errors
Read this comment first
The reason why this occurs is that you are likely trying to use a pre-compiled (to JS) component that was compiled with a different Svelte version than the one you use, which is not supported. See this comment for more info and solutions: https://github.com/sveltejs/svelte/issues/6584#issuecomment-1019578529
Describe the bug
I recently experienced issues due to new root property in several svelte plugins.
It seems that this line causes issues: https://github.com/sveltejs/svelte/commit/5cfefeb6e72f8085e418150b644cdc4b4f6f260d#diff-da9bae4e28c441de5ba3a074e30775fe69109100b3d921ad8f2592d93cd67b7f
It seems that a null check for parent_component variable is missing at that point.
on_mount: [],
on_destroy: [],
on_disconnect: [],
before_update: [],
after_update: [],
context: new Map(parent_component ? parent_component.$$.context : options.context || []), // Here, there is a null check for parent_component variable
// everything else
callbacks: blank_object(),
dirty,
skip_bound: false,
root: options.target || parent_component.$$.root // Here there is no check for parent_component variable
Reproduction
This suddenly occured on certain svelte plugins.
Logs
No response
System Info
System:
OS: Linux 5.8 Debian GNU/Linux 10 (buster) 10 (buster)
CPU: (8) x64 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
Memory: 517.19 MB / 7.47 GB
Container: Yes
Shell: 5.0.3 - /bin/bash
Binaries:
Node: 16.0.0 - ~/.n/bin/node
npm: 7.10.0 - ~/.n/bin/npm
npmPackages:
svelte: ^3.31.2 => 3.38.3
webpack: ^5.16.0 => 5.44.0
Severity
blocking an upgrade
Experiencing the same issue. I had svelte app, which includes npm svelte component and it throws this error:

This is my simplified code snippet:
/** app.js */
<script>
import Example from './example.svelte';
new Example({ target: document.body });
</script>
/** example.svelte **/
<script>
import Svelecte from 'svelecte';
</script>
<Svelecte></Svelecte> <!-- when I add component, it breaks -->
It's strange that context property will check for existence of parent_component but the new root property won't.
@mskocik I had the exact same error from plugins that had bundles using latest svelte version.
This also occurs when sharing components with webpacks module federation. (In the current version of svelte, older versions work). An example is here: https://github.com/micschwarz/svelte-module-federation
I've been racking my brain for the last 3 hours trying to figure out why my app suddenly started exploding... Eventually managed to find this issue. Is there a simple fix to reverting this bug so I can continue development until it's patched? I'm using esbuild-svelte which is pulling in a broken version I guess, so I can't just define an older version of svelte in my package.json as far as I'm aware?
For others trying to Google this issue, the console output for Chrome is:
Uncaught (in promise) TypeError: Cannot read property '$$' of null
And for Firefox:
Uncaught (in promise) TypeError: parent_component is null
Try downgrading svelte version until it works again. Version 3.39.0 worked fine for me.
On 30. 7. 2021 12:01, nullbio wrote:
I've been racking my brain for the last 3 hours trying to figure out why my app suddenly started exploding... Is there a simple fix to reverting this bug so I can continue development until it's patched?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/sveltejs/svelte/issues/6584#issuecomment-889783745, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGCU5FABFDMDYYYU3OTM6PTT2JZ7BANCNFSM5BCL6OBQ.
Try downgrading svelte version until it works again. Version
3.39.0worked fine for me. … On 30. 7. 2021 12:01, nullbio wrote: I've been racking my brain for the last 3 hours trying to figure out why my app suddenly started exploding... Is there a simple fix to reverting this bug so I can continue development until it's patched? — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub <#6584 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGCU5FABFDMDYYYU3OTM6PTT2JZ7BANCNFSM5BCL6OBQ.
Thanks. Clearing my package-lock.json, node_modules, and adding "svelte": "3.39.0", to my package.json seems to have worked. Didn't think it would because in my build svelte is a dependency of esbuild-svelte, but I suppose in the land of node it enforces a version for sub-dependencies if you declare one explicitly. News to me. Just leaving this here for anyone else who needs it and is new to all of this like I am.
This breaks on Snowpack's streaming imports where you don't have the svelte/compiler available and it just downloads ESM modules... so, for componentes that were already generated this way then there's no solution.
Sticking to v3.39.0 is fine if you're bundling all way long, but CDN-based approaches are failing due this.
Until #6646 gets merged CDN users are just blocked.
Thank you!
does this issue solved? the same error occurs to me.
Why is this code ever getting called with neither a target passed in to the constructor nor current_component/parent_component being set?
If it's one Svelte component trying to use another pre-compiled pre-bundled Svelte component, there are already other known issues with that (problems with the transitions scheduler, context not inheriting, probably others), and it's not something that's supported.
What's the use case here? Would the change in #6646 prevent this immediate crash, but still leave the other less-visible issues with apps being bundled with multiple copies of Svelte's internals?
@Conduitry
What's the use case here?
Microfrontends are the use case :)
Would the change in #6646 prevent this immediate crash, but still leave the other less-visible issues with apps being bundled with multiple copies of Svelte's internals?
The change in #6646 would prevent this, yes.
Of course the other issues would still exist, but if you use svelte this way, you might be aware of them.
A possibly related post on Reddit: https://www.reddit.com/r/sveltejs/comments/pjo902/svelte_microfrontend_module_federation_bug/?utm_medium=android_app&utm_source=share
I'm getting same error and I've tried downgrading to 3.39.0 and using 3.43.0 latest but still get it:

My use case is I have a ui component library I'm attempting to prepare for publishing -- I've npm linked to a ui library which I've built out a dist/index.js via rollup -c and when I try to use it with following I get said error:
<script>
import { Button } from 'agnosticui-svelte';
</script>
<main>
<Button mode="primary" isBordered>Testing 1234</Button>
</main>
<style></style>
I've used https://github.com/joeattardi/svelte-tabs and built it out a similar way and it doesn't have the issue but it's locked back at 3.7.1:
"svelte": {
"version": "3.7.1",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-3.7.1.tgz",
"integrity": "sha512-MKjFy3YZ2pNUVPTwLNQ9JAVx6KVwfYnm/vbUF/pKLrfDDZiCBKfWPwnffpwGlnIAn7aS+aJoKV0soj464DOs4Q==",
"dev": true
},
I tried rolling all the way back to 3.7.1 in my project, and I still have same exact error. So that tells me perhaps there's something different (and wrong) between what I'm doing and what svelte-tabs.
UPDATE:
I just deleted all my components and copied over the very simple svelte-tabs components and updated my example app to look exactly like his. I can reproduce same exact error with svelte v3.43.0.
Then, I backed down my package.json for the library and for the example app the was npm linked to "svelte": "3.39.0"`, removed both lock files and reinstalled. I was able to run the example. So, there's something specific in my components that still was causing the error even after downgrading; so I'll have to just add my components back one at a time to figure that out. However, it looks like this is definitely a bug on the latest version.
This seems like a blocker for anyone trying to develop a component library.
Hello,
I do have the same issue in my app while trying to test a component which contains an "if" statement and a mock module. I did not have the issue back when I was using Svelte 3.35.0. I tried to upgrade yesterday to 3.43.0, but did not succeed. I had to rollback to 3.39.0.
To ease a bit the debug, here's a simplified repo to reproduce the issue: https://github.com/gcruchon/tests/tree/main/svelte-null-parent-component
I'm using last version of all libraries (svelte, jest, svelte-jester, babel, testing-library, ...). I used the svelte template and just added the bug (i.e. testing a mocked "Link" within an "if" statement)
Feel free to comment if I missed something.
Re @mskocik I tested your example in a REPL and I don't see any errors.
Re streaming imports @pateketrueke I'm not familiar with it, but usually using CDN or pre-bundled code for Svelte components, they should always be instantiated with a target to mount to. Svelte doesn't guarantee components to work cross version AFAIK, so target would help "isolate" it.
Re jest mocks @gcruchon that seems like a bug of how Svelte components are mocked and interacting with the component initialization phase. I'm not familiar with how it works under-the-hood, but probably somewhere multiple svelte instances are created when being bundled (?).
I agree with Conduitry here. While the PR that fixes this works, I don't see any reason why the error would happen in the first place. Either options.target is defined for the component to mount to, or it has a parent_component. It shouldn't be dangling around without a reference. If anything, versions above 3.39.0 have surfaced many implementation bugs around the ecosystem, and we should fix them instead. And they largely seem to be components not being compiled/bundled correctly.
@bluwy Cannot duplicate in the REPL neither. But it was happening. It was quite hard to replicate back then. But since when I tried 3.43.1 it worked for me since then.
Re @mskocik that seems like a bug of how Svelte components are mocked and interacting with the component initialization phase. I'm not familiar with how it works under-the-hood, but probably somewhere multiple svelte instances are created when being bundled (?).
Thanks for acknowledging this bug.
If I’m not mocking svelte component in the right way, how would you recommend to mock a svelte component? Using an import of a much simpler .svelte file seems to me pretty simple and straightforward… how come this works without if statement and suddenly fails with an if?
I’m not a specialist of the svelte compiler, so I need more info to investigate. Can someone help me understand and improve the maturity of Svelte to embrace such software craftsmanship practices?
Do you have all what is necessary to reproduce the bug? (I see a label “need repro”)
If I’m not mocking svelte component in the right way, how would you recommend to mock a svelte component?
The way you mock it now is correct, but I'm guessing there's a bug when transforming svelte files in jest. Might be an issue in https://github.com/mihar-22/svelte-jester.
Do you have all what is necessary to reproduce the bug? (I see a label “need repro”)
I'd say a no since the repros given so far are Svelte + [third-party integration] repros. Maybe it's fair as it only happens in these very specific scenarios, but it makes it hard to nail down what actually is the bug in Svelte. Or the real bug resides in that third-party integration.
@nullbio I was also getting this error with Esbuild and it seemed to happen when I linked other libraries that also included svelte. Esbuild wasn't de-duping the svelte import, so I was getting multiple copies inside my bundle. I couldn't find a plugin to de-dupe svelte so added this inline one.
// part of esbuild config
plugins: [
{
name: 'dedupe-svelte',
setup({ onResolve }) {
const svelte = require.resolve('svelte')
onResolve({ filter: /^svelte/ }, args => {
let path = svelte.replace(/svelte\/[^\.]+.js$/,args.path+"/index.mjs")// .mjs for browser path
return { path }
})
}
},
sveltePlugin({compileOptions: {css: true}})
],
Hope that helps.
Just adding another data point for why this error occurred for me — I was consuming an internal design system where svelte was listed as a dependency rather than peerDependency, resulting in multiple instances existing in my app (verified by running yarn why svelte). Fixing that so only one svelte instance (regardless of version) was installed fixed the issue for me.
I agree with the sentiment that if anything recent versions of Svelte have just surfaced ecosystem issues. Could svelte throw a more useful error? From reading this thread seems it's often due to mismatching/several versions of svelte existing at once.
EDIT: This also happened when I yarn linked said design system for local development, presumably for the same reason, which is frustrating. I got around it by also linking the svelte instance in the design system, which feels hacky.
Could svelte throw a more useful error?
Yes, we could do that as it's detectable.
This also happened when I
yarn linked said design system for local development, presumably for the same reason, which is frustrating. I got around it by also linking the svelte instance in the design system, which feels hacky.
I have a design system component library as well and have not encountered this issue. Are you compiling the library into JS? Make sure to export raw Svelte files instead so that the consumer of that library can share the Svelte instance.
For what it's worth, I'm going to add my boring story of how I came across this error 🤷 In a progressively-enhanced PHP app, I used to create svelte components regardless of whether the target existed or not, because one main.js file creates components on different pages that don't always use all of them. Svelte used to handle this gracefully, skipping those components that didn't have a valid target element. After I updated svelte from 3.38.3 to 3.44.2, I came across this error. Either I missed it while browsing through or this “change” in behavior wasn't mentioned in the changelog. 🤭
I added a conditional checking for the element to exist before creating a component, which seems more reasonable anyways.
Having gone through the debugging process, I can however confirm that catching the error and printing a more specific error message could be nice if both, target and parent are undefined for one or another reason.
I've been having issues with this recently, such as when using svelte-loader + svelte with electron-forge

https://github.com/sveltejs/svelte/pull/6646 What about this pr? Its open for month now
So this was breaking components that couldn’t be server-side rendered and so had to be instantiated using <svelte:component> in NodeKit.
In case anyone else comes across this Svelte bug while using their Svelte plugin with esbuild, you can apply the patch in #6646 in your plugin’s build onEnd() handler:
await esbuild.build({
//…
plugins: [
sveltePlugin(route),
{
name: 'Apply patches',
setup(build) {
build.onEnd(result => {
// Apply PR: https://github.com/sveltejs/svelte/pull/6646/files
// by https://github.com/hgiesel
if (result.outputFiles) {
result.outputFiles.forEach((outputFile, index) => {
// Note $$ is escaped as $$$$.
const patchedResult = outputFile.text.replace(/root: options\.target \|\| parent_component\.\$\$\.root/g, 'root: options.target || (parent_component ? parent_component.$$$$.root : document)')
result.outputFiles[index].contents = Buffer.from(patchedResult, 'utf-8')
})
}
})
}
}
]
})
This does, however, slow down the esbuild build so I do hope that #6646 will be accepted.
In case it helps, I was testing with the svelte-boring-avatars and tsParticles components. Both break without the patch.
With the patch, svelte-boring-avatars works but, since the distribution build for tsParticles is minified, the patch doesn’t apply and that’s still failing.
So I guess the only option left is to patch Svelte itself.
Esbuild wasn't de-duping the svelte import, so I was getting multiple copies inside my bundle.
It’s odd because I’m using a custom resolver in my esbuild to ensure that all Svelte references get mapped to the single instance of Svelte that’s in my app. And I’m still seeing this error (see above).
The problem here is instantiating a component compiled with Svelte version X inside an app compiled with Svelte version Y in a declarative way.
The following is not guaranteed to work:
<CompiledComponent />
<svelte:element this={CompiledComponent} />
The following will work:
<script>
//..import
let el;
onMount(() => new CompiledComponent({target: el, props: {..}));
</script>
<div bind:this={el} />
If using a component from a library, ensure that an uncompiled version exists and is used by your build tool. SvelteKit's package command ensures this for example.
@dummdidumm Hey Simon, thank you, that does indeed work. I’m going to see how I can incorporate checking if the source exists for a component and using that in my loader’s resolution. I’m assuming that’s what the svelte entries in the package.json files are for. Appreciate your help.
If it's one Svelte component trying to use another pre-compiled pre-bundled Svelte component, there are already other known issues with that (problems with the transitions scheduler,
contextnot inheriting, probably others), and it's not something that's supported.
@Conduitry There should be a big warning in the Svelte doc that using pre-bundled Svelte components is not supported. It's a blocker for our project and probably for some others too.
@jindrahm Agreed; @Conduitry this could also be mentioned in the Svelte FAQ, or Svelte Society. I'm trying to downgrade as well; I'm just trying to re-spin up nodemon real quick.
:heavy_check_mark: Got it on my end; make sure to run:
> npm i -s svelte@^3.39.0
# for yarn:
> yarn add svelte@^3.39.0
So npm/yarn knows to downgrade.
However, I can see this tripping other newbies up as there's nothing mentioned in the Svelte docs/FAQ/Society; I think this is very essential for the Svelte ecosystem/community to be aware of as an error like this can hinder the modularity of a Svelte app.