-
-
Notifications
You must be signed in to change notification settings - Fork 4.6k
Description
Describe the bug
I was a little silly today and somehow mixed up @render
and @html
.
Easy fix, but unfortunately the error message is incredibly unhelpful:
TypeError: Cannot read properties of undefined (reading 'out')
at children (<snip>/src/routes/+page.svelte:13:4) [1]
at Component (<snip>\src\lib\Component.svelte:7:8) [2]
<snip>
The sourcemap's line numbers weren't particularly useful either, so I went digging in the generated _page.svelte.js
.
After some fiddling I found that a component like this:
<script lang="ts">
import type { Snippet } from 'svelte';
let { children }: { children: Snippet } = $props();
</script>
<!-- Bad -->
{@html children()}
<!-- Good -->
{@render children()}
...compiles roughly to this:
function Component($$payload, $$props) {
push();
let { children } = $$props;
// {@html children()}
// Bad: children expects $$payload parameter
$$payload.out += `${html(children())}`; // [2]
// {@render children()}
// Good: children gets $$payload parameter
children($$payload);
$$payload.out += `<!---->`;
pop();
}
function _page($$payload) {
Component($$payload, {
children: ($$payload2) => {
// Error: $$payload2 is undefined :(
$$payload2.out += `<!---->Content`; // [1]
}
});
}
I know next to nothing about Svelte's internals, but I suppose invoking a Snippet
inside @render
gets special treatment from the compiler to insert the hidden $$payload
parameter. This doesn't happen in other situations, therefore it blows up at runtime.
The JSDoc for Snippet
says:
You can only call a snippet through the
{@render ...}
tag.
That makes sense to me, but it doesn't seem to be enforced in any way, nor is it mentioned on the docs page. I don't see a way to encode this into the type system, so I'd suggest adding an explicit error message. Preferably at compile time if possible, but a helpful runtime error would already be a great improvement :)
Reproduction
System Info
System:
OS: Windows 10 10.0.19045
CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
Memory: 15.74 GB / 31.81 GB
Binaries:
Node: 20.18.0 - C:\Program Files\nodejs\node.EXE
npm: 10.9.0 - C:\Program Files\nodejs\npm.CMD
pnpm: 8.9.2 - ~\AppData\Local\pnpm\pnpm.EXE
Browsers:
Edge: Chromium (133.0.3065.69)
Internet Explorer: 11.0.19041.4355
npmPackages:
svelte: ^5.0.0 => 5.23.0
Severity
annoyance