Repository navigation
fix(demo): keep CauseView's rows stable when a batch commits - #44
Merged
Merged
Conversation
CauseView keyed its rows with a counter bumped on every evaluation of a
$derived. With async Svelte, a keyed each block re-reads its list when a batch
commits, got keys none of its rows had, and threw "Cannot read properties of
undefined (reading 'e')". It happened on the RPC page's "Todo 99" button, every
time in production, and in dev with overlapping requests. The list now sits in
a {#key cause} block, so a new cause remounts it (its rows still slide in) and
the rows need no keys. The e2e test checks the page logs no errors.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
jarrednorrisdev
force-pushed
the
fix/demo-cause-view-keys
branch
from
October 10, 2026 00:57
2823609 to
b7d3ce1
Compare
jarrednorrisdev
marked this pull request as ready for review
October 10, 2026 01:02
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes an uncaught error on the docs site's RPC page. Only the demo changes; no package is released.
CauseViewis the docs site's component that shows an EffectCause(the record of why an effect failed) as one row per reason.Clicking "Todo 99" throws in the console
$derived(Svelte 5) is a value Svelte recalculates when what it reads changes, and Svelte expects it to have no side effects.{#each list as row (row.key)}is a keyed list: Svelte matches each rendered row to an item by its key.Bug: clicking Todo 99 logs
Cannot read properties of undefined (reading 'e'). It happens on every click in the production build, and invite devwhen requests overlap (Todo 2, then Todo 99 while the first is still loading). The page still shows the right result. The error comes from async Svelte (experimental.async, which this site turns on): when it applies a batch of updates, the keyed list readskeyedagain,keyedevaluates again and the counter goes up. So the keys it gets back match none of the rows already on screen, and Svelte's row matching (reconcileineach.js) looks up a row that isn't there.Fix: the list sits in a
{#key cause}block and its rows need no keys.{#key value}destroys and rebuilds what it wraps whenevervaluechanges. So a new cause still rebuilds the list and its rows still slide in, while reading the same cause again changes nothing.Tests
The e2e test "RPC page › add, typed error, toggle and the query family" now records the page's errors and ends with
expect(await errors()).toEqual([]). Without the fix it fails, logging exactly that error (chromium, production build).svelte-checkon the demo: 0 errors, 0 warnings. The full e2e suite passes in CI in chromium, firefox and webkit with this change.Decisions
{#key cause}instead of keying rows by the cause object. The first version of this PR kept the keyed list and gave each cause its own number through aWeakMap<Cause, number>. That worked, but it needed a counter, a map and a helper to get the same effect a{#key}block gets with no script at all.await_reactivity_losswarning on /suspense. It comes from Svelte's own$effect.pending()runtime, not from this repo.Where to look in the diff
apps/demo/src/lib/docs/kit/cause-view.svelte: removeskeyedandgeneration; the list is wrapped in{#key cause}.apps/demo/e2e/demo.test.ts: "RPC page › add, typed error, toggle and the query family" useswatch(page)and checkserrors()..changeset/quick-mammals-smoke.md: an empty changeset, because only the demo changes.🤖 Generated with Claude Code