Skip to content

fix: keep dependencies of $state.eager/pending (alternative approach)#18218

Merged
Rich-Harris merged 8 commits into
mainfrom
eager-block-fix-alt
May 14, 2026
Merged

fix: keep dependencies of $state.eager/pending (alternative approach)#18218
Rich-Harris merged 8 commits into
mainfrom
eager-block-fix-alt

Conversation

@Rich-Harris

@Rich-Harris Rich-Harris commented May 14, 2026

Copy link
Copy Markdown
Member

#18108, with two differences:

  • we use a global map
  • we use the parent reaction as the key, rather than traversing upwards for a branch

I think this has the same outcome?

Fixes #18095

Before submitting the PR, please make sure you do the following

  • It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
  • Prefix your PR title with feat:, fix:, chore:, or docs:.
  • This message body should clearly illustrate what problems it solves.
  • Ideally, include a test that fails without this PR but passes with it.
  • If this PR changes code within packages/svelte/src, add a changeset (npx changeset).

Tests and linting

  • Run the tests with pnpm test and lint the project with pnpm lint

dummdidumm and others added 7 commits April 13, 2026 23:32
When an eager effect reruns, its version source is destroyed and recreated. That means all dependencies are lost. This breaks when the following is all true:
- `$state.eager` is (indirectly) used in a block effect
- it is scheduled to rerun
- another source (or the same as within `$state.eager`) is (also) dirty and scheduled to rerun in a microtask _before_ `flush_eager` runs

... then `flush_eager` runs the version sources with outdated (or rather, `null`ed) reactions, resulting in nothing being rerun.

The fix is to have a stable `version` source across `eager` executions. Fixes #18095
@changeset-bot

changeset-bot Bot commented May 14, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 451870a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
svelte Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@svelte-docs-bot

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown
Contributor

Playground

pnpm add https://pkg.pr.new/svelte@18218

@dummdidumm

Copy link
Copy Markdown
Member

reaction isn't guaranteed to be non-null so we should do one of these

  • guard against that throw
  • handle this as "not part of a map, recreated every time"
  • do what you do currently and just have them share a source (though teardown will not run then either..? So likely the worst option)

Other than that this should work 👍

@Rich-Harris

Copy link
Copy Markdown
Member Author

Honestly I thought we'd already error in this case because of the eager_effect call directly below, but it turns out we don't error if you create an effect outside an effect tree, if it's not a user effect? TIL.

Anyway, simplest and most forgiving fix is to just return fn() immediately in that case, so that's what I did.

@Rich-Harris Rich-Harris merged commit a10e8e4 into main May 14, 2026
21 checks passed
@Rich-Harris Rich-Harris deleted the eager-block-fix-alt branch May 14, 2026 17:31
@github-actions github-actions Bot mentioned this pull request May 14, 2026
Rich-Harris pushed a commit that referenced this pull request May 14, 2026
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## svelte@5.55.6

### Patch Changes

- fix: leave stale promises to wait for a later resolution, instead of
rejecting ([#18180](#18180))

- fix: keep dependencies of `$state.eager/pending`
([#18218](#18218))

- fix: reapply context after transforming error during SSR
([#18099](#18099))

- fix: don't rebase just-created batches
([#18117](#18117))

- chore: allow `null` for `pending` in typings
([#18201](#18201))

- fix: flush eager effects in production
([#18107](#18107))

- fix: rethrow error of failed iterable after calling `return()`
([#18169](#18169))

- fix: account for proxified instance when updating `bind:this`
([#18147](#18147))

- fix: ensure scheduled batch is flushed if not obsolete
([#18131](#18131))

- fix: resolve stale deriveds with latest value
([#18167](#18167))

- chore: remove unnecessary `increment_pending` calls
([#18183](#18183))

- fix: correctly compile component member expressions for SSR
([#18192](#18192))

- fix: reset `source.updated` stack traces after `flush`
([#18196](#18196))

- fix: replacing async 'blocking' strategy with 'merging'
([#18205](#18205))

- fix: allow `@debug` tags to reference awaited variables
([#18138](#18138))

- fix: re-run fallback props if dependencies update
([#18146](#18146))

- fix: abort running obsolete async branches
([#18118](#18118))

- fix: ignore comments when reading CSS values
([#18153](#18153))

- fix: wrap `Promise.all` in `save` during SSR
([#18178](#18178))

- fix: ignore false-positive errors of `$inspect` dependencies
([#18106](#18106))

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

$effect.pending() with $state.eager broken

2 participants