sveltejs/svelte · error · Error
each_key_duplicate
each_key_duplicate
Error message
each_key_duplicate
${value ? `Keyed each block has duplicate key `${value}` at indexes ${a} and ${b}` : `Keyed each block has duplicate key at indexes ${a} and ${b}`}
https://svelte.dev/e/each_key_duplicate What it means
Runtime error `each_key_duplicate`: a keyed `{#each items as item (key)}` block produced the same key value for two different items at the same indexes `a` and `b`. Svelte keys must be unique per item so the diff/patch logic can track elements. The key value is included when available, omitted otherwise.
Source
Thrown at packages/svelte/src/internal/client/errors.js:146
/**
* Keyed each block has duplicate key `%value%` at indexes %a% and %b%
* @param {string} a
* @param {string} b
* @param {string | undefined | null} [value]
* @returns {never}
*/
export function each_key_duplicate(a, b, value) {
if (DEV) {
const error = new Error(`each_key_duplicate\n${value
? `Keyed each block has duplicate key \`${value}\` at indexes ${a} and ${b}`
: `Keyed each block has duplicate key at indexes ${a} and ${b}`}\nhttps://svelte.dev/e/each_key_duplicate`);
error.name = 'Svelte error';
throw error;
} else {
throw new Error(`https://svelte.dev/e/each_key_duplicate`);
}
}
/**
* 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 {View on GitHub (pinned to 20b341f100)
Solutions
- Use a truly unique key — typically the item's primary key (`(item.id)`).
- If the data has no unique field, derive one (e.g. compose `(item.type + '-' + item.id)`) or sanitize duplicates upstream.
- Avoid `(index)` as the key when the list can be reordered, inserted into, or filtered.
Example fix
{#each items as item (item.status)} <!-- duplicate statuses -->
{#each items as item (item.id)} <!-- unique --> Defensive patterns
Strategy: validation
Validate before calling
// Detect non-unique keys in a list before render (data-side check).
function findDuplicateKeys(items, keyFn) {
const seen = new Map();
const dups = [];
for (let i = 0; i < items.length; i++) {
const k = keyFn(items[i]);
if (seen.has(k)) dups.push({ key: k, a: seen.get(k), b: i });
else seen.set(k, i);
}
return dups;
} Prevention
- Key `{#each}` on a guaranteed-unique field (typically the entity ID).
- Validate list data upstream to reject duplicate IDs before render.
- Never key on array index when the list can be reordered or filtered.
When it happens
Trigger: At runtime (DEV) when the keyed-each reconciler detects that two items in the same list yield identical keys. Common with `(item.id)` when IDs collide, or with `(index)`-style keys when items reorder.
Common situations: Backend returning duplicate IDs in a list; using a non-unique field (e.g. `(item.status)`) as the key; merging two lists that share keys; using array index as key while inserting/removing items.
Related errors
- each_key_volatile
- 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/08385890bf7a6b1b.
Report an issue: GitHub.