fix: detect and error on non-idempotent each block keys in dev mode
#17732
Closing issue
Describe the bug
https://svelte.dev/docs/svelte/each#Keyed-each-blocks
The key can be any object
So I tried using array as a key for #each block:
{#each things as thing ([thing.group, thing.id])}
Works fine when page loads, but when data changes, it throws error.
Had to convert to string in order to get it working:
{#each things as thing ([thing.group, thing.id].join('-')}
So either docs need updating, or #each needs fixing to support array keys
Reproduction
https://svelte.dev/playground/1db5362a3e974b209b11ae389758c93f?version=5.51.2
Click button, check browser console.
Logs
playground:output:5619 Uncaught TypeError: Cannot read properties of undefined (reading 'e')
at reconcile (playground:output:5619:54)
at commit (playground:output:5450:4)
at Batch.process (playground:output:1109:46)
at flush_effects (playground:output:1484:11)
at Batch.flush (playground:output:1244:5)
at Array.eval (playground:output:1417:13)
at run_all (playground:output:126:10)
at run_micro_tasks (playground:output:739:3)
at eval (playground:output:757:32)
System Info
System:
OS: macOS 26.3
CPU: (14) arm64 Apple M4 Pro
Memory: 439.02 MB / 24.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 24.10.0 - /Users/kieran/.local/share/mise/installs/node/24.10.0/bin/node
npm: 11.6.1 - /Users/kieran/.local/share/mise/installs/node/24.10.0/bin/npm
pnpm: 10.29.3 - /Users/kieran/.local/share/mise/installs/node/24.10.0/bin/pnpm
npmPackages:
svelte: 5.51.0 => 5.51.0
Severity
annoyance
Pull request
Summary
Fixes #17721
In dev mode, detect when a keyed each block has a key function that returns different values when called multiple times for the same item (non-idempotent). This catches the common mistake of using array literals like [thing.group, thing.id] as keys, which creates a new array object each time and will never match by reference.
- Adds new
each_key_volatileerror with helpful message explaining the issue - Checks key idempotency in the each block loop during dev mode
- Provides a clear error instead of the cryptic "Cannot read properties of undefined" that occurred previously
Info
🦋 Changeset detected
Latest commit: 91d0454
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
pnpm add https://pkg.pr.new/svelte@17732The docs for #each still say "The key can be any object" but this is not the case anymore, since using an array or object will now result in an each_key_volatile exception: https://github.com/sveltejs/svelte/blob/3f6521df0e1c476b85f704b8aded0303be8eb4b4/documentation/docs/03-template-syntax/03-each.md?plain=1#L51
No, it still can be an object; it just must be the same object each time.
@7nik Hmm, then the docs may cause confusion. "The key can be any object" makes me think I can use an array of values, or an JS object, but now both of those will result in a each_key_volatile exception (and understandably so), so "any object" is incorrect.
Perhaps it could be reworded as such:
The key can be any idempotent value; that is, the same object created twice must be strictly identical (i.e. `===`). Strings and numbers are recommended.
I'm happy to create a PR if this change would be accepted.
That wording doesn't really make sense — there's no such thing as an 'idempotent value' (idempotency is a property of functions), and 'the same object created twice' is self-contradictory.
Personally I think the existing wording is clear enough, but in the event that someone does hit each_key_volatile they will be led , which explains the behaviour.
Here is .
This PR forbids nothing new. It just adds throwing a descriptive error instead of a cryptic one.
Having the warning in development that using a key is not supported is useful, but even with this PR, if you change {#each objs as obj (obj.a)} to {#each objs as obj ([obj.a])} and deploy to production, it will still raise an cryptic exception instead of accepting it as a valid key and still running (even if it means quality doesn't match and extra work is performed).
If you're saying that ([obj.a]) is not a valid each key that can be used, then the docs phrasing of "The key can be any object" doesn't seem to align for me (as [obj.a] == any object), but this isn't a hill I'm willing to die on ^_^ So I'll leave there :-) Appreciate all the hard work you all do. Thank you.
fix: detect and error on non-idempotent each block keys in dev mode
• Feb 17, 2026, 6:53 PMCo-authored-by: 7nik <[email protected]>
Pro 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 ;)