kit icon indicating copy to clipboard operation
kit copied to clipboard

Inconsistent page.params reactivity in top level async derived

Open jkbz64 opened this issue 1 month ago • 2 comments

Describe the bug

When page.params param is used in a top level await derived it sometimes gets updated (without a reactivity change) after the top-level await executes but the value should always be known and updated before running the top level await/component.

Reproduction

Svelte: 5.45.2

SvelteLab

Click on any route link in main route, it should always return 1 length but it very often returns 0 then go back and re-entry it, click it enough times and it returns 0.

As a workaround you can store the value in some global state before navigating with goto instead of using <a> link.

https://github.com/user-attachments/assets/0b4ae3fc-a048-419e-a8da-f175c75940b6

Logs


System Info

System:
    OS: Linux 6.14 Fedora Linux Asahi Remix 42 (Forty Two [Adams])
    CPU: (8) arm64 unknown
    Memory: 7.42 GB / 31.11 GB
    Container: Yes
    Shell: 5.9 - /usr/bin/zsh
  Binaries:
    Node: 22.19.0 - /home/jk/.n/bin/node
    Yarn: 1.22.22 - /home/jk/.n/bin/yarn
    npm: 10.9.3 - /home/jk/.n/bin/npm
    bun: 1.3.3 - /home/jk/.bun/bin/bun
  Browsers:
    Chromium: 142.0.7444.175
    Firefox: 145.0.1
    Firefox Developer Edition: 145.0.1

Severity

serious, but I can work around it

Additional Information

No response

jkbz64 avatar Nov 27 '25 10:11 jkbz64

You sure the syntax is correct? This is working.

-let result = $derived(await map(test(), (x) => x === +page.params.x));
+let result = $derived(map(await test(), (x) => x == page.params.x));

Note: your array contains number while params.x is always string. I use == for a quick check but you should use the correct type and compare using ===.

henrykrinkle01 avatar Nov 27 '25 10:11 henrykrinkle01

You sure the syntax is correct? This is working.

-let result = $derived(await map(test(), (x) => x === +page.params.x)); +let result = $derived(map(await test(), (x) => x == page.params.x));

Note: your array contains number while params.x is always string. I use == for a quick check but you should use the correct type and compare using ===.

It's using +page.params.x so the string is converted to number anyway, your invocation is very different than mine too because you are awaiting before going into the function then awaiting non-promise inside the function.

jkbz64 avatar Nov 27 '25 10:11 jkbz64