-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Description
Describe the bug
This is a weird one. Let's say you have two remote functions, one that gets a counter, one that increments it.
import { query, command } from '$app/server';
let counter = 0;
export const incCounter = command(async () => {
counter++;
//getCounter().refresh() (no refresh just yet, uncomment in the next step)
});
export const getCounter = query(async () => {
return counter;
});Now let's say we have a button that increments a counter, and beneath it we have the "event history" component, which should show the history of the values.
<script lang="ts">
import {getCounter,incCounter} from './repro.remote'
import Event from '$lib/Event.svelte'
const counterHist:number[] = $state([])
const c = $derived(await getCounter())
</script>
{c}
<button onclick={async () => {
await incCounter()
counterHist.push(c + 1)
}}>counter++</button>
<ul>
{#each counterHist as h}
<li>
<Event c={h}/>
</li>
{/each}
</ul>The Event component just shows some text, and the value of the counter that was provided to it. It also shows a boolean that is set to true in its onMount, so it should only print true (foreshadowing).
<script lang="ts">
import {onMount} from 'svelte'
let mounted = $state(false)
const {c} = $props()
onMount(() => {
mounted = true
})
</script>
Inc counter from {c} ------> {mounted}Now the refresh in incCounter is commented, so let's click the button a bunch of times:
Inc counter from 1 ------> true
Inc counter from 1 ------> true
So far, so basic. The counter shown remains at 1 (obvious, since we don't call refresh yet) and the boolean is true (obvious because how could it not be?)
Now let's uncomment the refresh for the getCounter in the incCounter function, refresh the page, and click the button a bunch more times
Inc counter from 1 ------> false
Inc counter from 2 ------> false
Inc counter from 3 ------> false
Inc counter from 4 ------> false
Inc counter from 5 ------> false
Ok, good, so the counter is incrementing but... what's this? The onMount no longer runs. And it only breaks with an {#each} block; I've tried with an {#if} and a boolean instead of a list, but it works. The refresh on remote functions just seem to break each blocks...
Reproduction
- Click the button a bunch of times
- Uncomment the refresh and then refresh the page
- Click the button again -> onMount no longer runs
Logs
N/ASystem Info
Svelte is not the latest version because of another bug ( #14843 ), but the stackblitz is on the latest svelte
System:
OS: macOS 26.0.1
CPU: (11) arm64 Apple M3 Pro
Memory: 123.41 MB / 18.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 24.10.0 - /opt/homebrew/bin/node
npm: 11.6.0 - /opt/homebrew/bin/npm
Deno: 2.5.4 - /opt/homebrew/bin/deno
Browsers:
Safari: 26.0.1
npmPackages:
@sveltejs/adapter-node: ^5.3.2 => 5.4.0
@sveltejs/kit: ^2.43.4 => 2.48.3
@sveltejs/vite-plugin-svelte: ^6.2.1 => 6.2.1
svelte: 5.42.2 => 5.42.2
vite: ^7.0.0 => 7.1.12Severity
blocking an upgrade
Additional Information
Not sure how to rank the annoyance. The bug messes up some pop-ups that auto-expire after 5 seconds, but the setTimeout to expire them is set in onMount, so they never disappear. The user can just click X to get them to go away, so in this case it's not the end of the world, but it may be a much more serious issue down the line...