Skip to content

bind:value causes stack overflow on 5.45.3 (in dev) when used with Bun #17288

@mackuba

Description

@mackuba

Describe the bug

I'm in the process of rewriting an app from pure vanilla JS to Svelte. I'm mostly done now, and today I've been moving a bunch of CSS from a single .css file to components.

At some point I've noticed that at least two unrelated components are causing a stack overflow:

HomeSearch.svelte:92 Uncaught RangeError: Maximum call stack size exceeded

	in <unknown>
	in App.svelte

    at get (HomeSearch.svelte:92:15)
    at get (HomeSearch.svelte:93:13)
    at get (HomeSearch.svelte:93:13)
    at get (HomeSearch.svelte:93:13)
    at get (HomeSearch.svelte:93:13)
    at get (HomeSearch.svelte:93:13)
    at get (HomeSearch.svelte:93:13)
    at get (HomeSearch.svelte:93:13)
    at get (HomeSearch.svelte:93:13)
    at get (HomeSearch.svelte:93:13)

Stack trace links point to a place in generated code that looks like this:

$.bind_value(
		input,
		function get() {
			return $.get(query);
		},
		function set($$value) {
			$.set(query, $$value);
		}
	);

At first I thought I broke something with the CSS changes, but I realized that I also installed the latest patch update at some point today.

This seems to be happening even in a component as simple as this:

<script>
  let query = $state('');
</script>

<input type="text" bind:value={query}>

After some debugging I found that this only happens if the bundler (Bun) runs in dev mode, not in production mode. The difference between the two versions of the bundle include a part like this, which seems to be the issue since changing this removes the issue:

<     bind_value(input, () => get(query), ($$value) => set(query, $$value));
---
>     bind_value(input, function get() {
>       return get(query);
>     }, function set($$value) {
>       set(query, $$value);
>     });

In version 5.45.2, both dev and prod builds create the top version. It seems to me that… this function get() is calling itself here? Which doesn't happen in the production version and in the previous release, where it was always printed as the arrow function.

This also seems to only happen if minification is turned off in the bundler (which I'm guessing renames such functions to some one-letter name).

My guess is that this is caused by this PR: #17269, and I think it might be somewhere in https://github.com/sveltejs/svelte/pull/17269/files#diff-59f747db7cbab9adbb6aa21ae06ab8558320d1e6b4fa43f209a0d5fe67ce01fe around this code:

if (dev) {
			// in dev, create named functions, so that `$inspect(...)` delivers
			// useful stack traces
			get = b.function(b.id('get', node.name_loc), [], b.block([b.return(expression)]));
			set = b.function(
				b.id('set', node.name_loc),

Reproduction

  • update to 5.45.3
  • build such component:
<script>
  let query = $state('');
</script>

<input type="text" bind:value={query}>
  • disable minification
  • make a development build
  • run app

Logs

System Info

n/a, running Bun

Severity

blocking an upgrade

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions