Skip to content

5.55.3: $derived first-read in out: transition returns UNINITIALIZED, crashes outro (now with REPL/Playground link) #18139

@briocheburger

Description

@briocheburger

Describe the bug

[following is created by Opus 4.7, hope that's fine, feel free to remove and/or request more info]

After upgrading from 5.55.2 to 5.55.3, a document-level click handler that calls store.set([]) no longer clears items rendered by a sibling {#each $store as item} block. The store write executes (verified by store.subscribe logging and by later reads), but the {#each} doesn't re-render, so the previously rendered DOM nodes stay visible.

Identical code is fine on 5.55.2, broken on 5.55.3, nothing else changed.

Bisect

5.25.8 ✓ → 5.40.0 ✓ → 5.47.0 ✓ → 5.51.0 ✓ → 5.53.0 ✓ → 5.54.0 ✓ → 5.55.0 ✓ → 5.55.2 ✓ → 5.55.3 ✗ → 5.55.4 ✗ → 5.55.5 ✗

Candidate from the 5.55.3 notes: fix: freeze deriveds once their containing effects are destroyed (#17921). Unconfirmed.

Abstract pattern

  // store.ts
  import { writable } from 'svelte/store'
  export const items = writable<string[]>([])

  <!-- Renderer.svelte -->
  <script lang="ts">
    import { items } from './store'
  </script>
  {#each $items as item}
    <div class="item-marker">{item}</div>
  {/each}

  <!-- Listener.svelte -->
  <script lang="ts">
    import { onMount } from 'svelte'
    import { items } from './store'

    onMount(() => {
      document.addEventListener('click', (event) => {
        const el = event.target as Element
        if (!el.closest('.item-marker')) {
          items.set([])   // executes on 5.55.3, but {#each} does not update
        }
      })
    })
  </script>

Reproduction

Reduction attempts (what does NOT reproduce)

I attempted to reduce this to a standalone Svelte Playground example on 5.55.3. The minimal pattern above works correctly in the Playground. I also tried these additions, all of which still worked correctly on 5.55.3:

  • Plain {#each} with text content
  • {#each} with in:fly|global + out:fly|global transitions
  • {#each} rendering a dynamic component via <item.component /> where the component internally uses $state and $derived

So the reduction surfaces a narrower picture: the bug needs something more than (document listener + store.set([]) + {#each $store}). The real application where this reproduces runs under SvelteKit with several nested wrapper components (four layers deep, each with their own effects and deriveds). I don't yet know which specific ingredient tips the balance.

What I've ruled out in the real app

  • Not a listener-attachment issue — the handler fires and items.set([]) executes (confirmed via store.subscribe).
  • Not an intermediate $derived($store) wrapper — removing one did not restore the behavior.
  • Not HMR — reproduces on production builds.
  • Not browser-specific.

Logs

System Info

svelte:   5.55.3 → 5.55.5 all broken; 5.55.2 last known good
  node:     22.x
  OS:       Linux
  Browser:  Chrome (latest stable)

Severity

annoyance, 5.55.2 pin is a workaround. Happy to help further reduce this with maintainer guidance — it'll likely need someone familiar with the internal changes in 5.55.3 to point at which additional ingredient is the trigger.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions