sveltejs/svelte · error · Error
each_key_volatile
each_key_volatile
Error message
each_key_volatile
Keyed each block has key that is not idempotent — the key for item at index ${index} was `${a}` but is now `${b}`. Keys must be the same each time for a given item
https://svelte.dev/e/each_key_volatile What it means
Runtime error `each_key_volatile`: the keyed-each key function returned a different value for the same item between renders (`a` then `b`). Keys must be idempotent — the same item must always produce the same key — otherwise the reconciler cannot track identity. The message shows the index and the two conflicting key values.
Source
Thrown at packages/svelte/src/internal/client/errors.js:165
}
}
/**
* Keyed each block has key that is not idempotent — the key for item at index %index% was `%a%` but is now `%b%`. Keys must be the same each time for a given item
* @param {string} index
* @param {string} a
* @param {string} b
* @returns {never}
*/
export function each_key_volatile(index, a, b) {
if (DEV) {
const error = new Error(`each_key_volatile\nKeyed each block has key that is not idempotent — the key for item at index ${index} was \`${a}\` but is now \`${b}\`. Keys must be the same each time for a given item\nhttps://svelte.dev/e/each_key_volatile`);
error.name = 'Svelte error';
throw error;
} else {
throw new Error(`https://svelte.dev/e/each_key_volatile`);
}
}
/**
* `%rune%` cannot be used inside an effect cleanup function
* @param {string} rune
* @returns {never}
*/
export function effect_in_teardown(rune) {
if (DEV) {
const error = new Error(`effect_in_teardown\n\`${rune}\` cannot be used inside an effect cleanup function\nhttps://svelte.dev/e/effect_in_teardown`);
error.name = 'Svelte error';
throw error;
} else {
throw new Error(`https://svelte.dev/e/effect_in_teardown`);
}View on GitHub (pinned to 20b341f100)
Solutions
- Key on a stable, immutable property of each item (an ID assigned once at creation).
- If items lack a stable ID, generate and assign one when the data is first loaded (e.g. via a `crypto.randomUUID()` map) and never change it.
- Remove any side effects or random values from the key expression.
Example fix
{#each items as item (Math.floor(Math.random()*1000))}
<!-- key changes every render -->
{#each items as item (item.id)}
<!-- stable id assigned at load --> Defensive patterns
Strategy: validation
Validate before calling
// Verify the key function is idempotent across two calls on the same item.
function isKeyIdempotent(items, keyFn) {
return items.every(item => keyFn(item) === keyFn(item));
}
// also assert no side effects / no randomness in the key expression:
function riskyKeyExpr(template) {
return /\(\s*(Math\.random|Date\.now|crypto\.)|\+\+|\-\-/.test(template);
} Prevention
- Key on a stable immutable property assigned once at item creation.
- If items lack IDs, generate them once when the data is loaded and store them on the item.
- Keep key expressions pure and free of side effects or randomness.
When it happens
Trigger: At runtime (DEV) when the keying function is non-deterministic or reads mutable state, e.g. `(Math.random())`, `(item.id++)`, `(Date.now())`, or a key that depends on a counter that changes each render.
Common situations: Using random/hash-of-object keys; keying on a property that the application mutates between renders; keying on an index that shifts as the list changes; objects whose `id` is assigned lazily on first access.
Related errors
- each_key_duplicate
- async_derived_orphan
- bind_invalid_checkbox_value
- bind_invalid_export
- bind_not_bindable
AI-assisted analysis of sveltejs/svelte@20b341f100 (2026-08-12).
Data as JSON: /api/errors/2809723ea6184148.
Report an issue: GitHub.