fix: preserve original boundary errors when keyed each rows are removed during async updates
#17843
Closing issue
Describe the bug
Honestly, the code explains the edge-case better than words:
<script>
let index = $state(0);
function fn(id) {
// When index changes to from 0 to 1, we explicitly simulate the undefined error
if (id === 2) throw new Error("Simulated TypeError");
}
</script>
<button onclick={() => index = 1}>Trigger</button>
<svelte:boundary>
{#snippet pending()}Loading...{/snippet}
{#snippet failed(error)}Error Caught: {error.message}{/snippet}
{#each [[1], [2]][index] as id (id)}
{@const result = await fn(id)}
{/each}
</svelte:boundary>
The result isn't even used, and fn isn't actually doing any async work, but the console will still log this cryptic error: TypeError: Cannot read properties of undefined (reading 'e') instead of the real error that was actually thrown.
It requires the error boundary to log (not 100% if that's just in the playground environment) and behaviour does not change by removing the pending snippet.
Also, I'm pretty sure that a $state mutation IS required for this to happen.
Reproduction
Logs
TypeError: Cannot read properties of undefined (reading 'e')
at reconcile (playground:output:5781:54)
at commit (playground:output:5604:4)
at Batch.flush (playground:output:1248:46)
at Batch.revive (playground:output:1390:9)
at Array.eval (playground:output:1369:11)
at run_all (playground:output:126:10)
at run_micro_tasks (playground:output:752:3)
at eval (playground:output:770:32)
System Info
playground with svelte `5.53.6`
Severity
annoyance
Pull request
Fixes a runtime edge case where keyed #each reconciliation can hit a missing item during deferred async updates, causing an internal crash and masking the original boundary error.
Fixes #17841
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:, ordocs:. - 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 testand lint the project withpnpm lint
Info
🦋 Changeset detected
Latest commit: 1200a82
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
Preserve boundary errors when keyed each rows are removed during async updates
• Mar 2, 2026, 6:16 PMPro tip: You can prefix GitHub URLs of issues, PRs or discussions with svcl.dev/ to view them on this page! Also try it on a GitHub release ;)