Skip to content

Svelte 5: $: generates wrong effect dependencies causing infinite loops. #9954

@brunnerh

Description

@brunnerh

Describe the bug

When setting a property on an object in a reactive statement, the object becomes a dependency.
This can easily cause infinite loop issues if multiple such statements exist, breaking compatibility with v4.

(Found by @kitschpatrol, relevant to svelte-tweakpane-ui)

Reproduction

<script>
	let button = { title: '', label: '' };
	let title = '';
	let label = '';

	title = label = ''; // to add dependencies/generate update block

	$: button.title = title;
	$: button.label = label;
</script>

REPL

Generated code:

$.pre_effect(() => {
	($.get(button), $.get(title));
	$.untrack(() => {
		$.mutate(button, $.get(button).title = $.get(title));
	});
});
$.pre_effect(() => {
	($.get(button), $.get(label));
	$.untrack(() => {
		$.mutate(button, $.get(button).label = $.get(label));
	});
});

Note the button dependency that is being added.


Same code in v4: REPL

$$self.$$.update = () => {
	if ($$self.$$.dirty & /*title*/ 1) {
		$: button.title = title;
	}
	if ($$self.$$.dirty & /*label*/ 2) {
		$: button.label = label;
	}
};

Logs

Uncaught Error: ERR_SVELTE_TOO_MANY_UPDATES: Maximum update depth exceeded. This can happen when a reactive block or effect repeatedly sets a new value. Svelte limits the number of nested updates to prevent infinite loops.
    at infinite_loop_guard (playground:output:445:10)
    at flush_queued_effects (playground:output:462:4)
    at process_microtask (playground:output:489:3)

System Info

REPL - v5.0.0-next.26

Severity

blocking an upgrade

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions