diff --git a/.changeset/sharp-snakes-poke.md b/.changeset/sharp-snakes-poke.md
new file mode 100644
index 0000000000..7f7f8aa7b2
--- /dev/null
+++ b/.changeset/sharp-snakes-poke.md
@@ -0,0 +1,5 @@
+---
+'svelte': patch
+---
+
+fix: emit `each_key_duplicate` error in production
diff --git a/packages/svelte/src/internal/client/dom/blocks/each.js b/packages/svelte/src/internal/client/dom/blocks/each.js
index 006bf09257..9a36f29158 100644
--- a/packages/svelte/src/internal/client/dom/blocks/each.js
+++ b/packages/svelte/src/internal/client/dom/blocks/each.js
@@ -42,6 +42,7 @@ import { active_effect, get } from '../../runtime.js';
import { DEV } from 'esm-env';
import { derived_safe_equal } from '../../reactivity/deriveds.js';
import { current_batch } from '../../reactivity/batch.js';
+import { each_key_duplicate } from '../../errors.js';
/**
* The row of a keyed each block that is currently updating. We track this
@@ -473,6 +474,21 @@ function reconcile(
var start = stashed[0];
var j;
+ // full key uniqueness check is dev-only,
+ // key duplicates cause crushing only due to `matched` being empty
+ if (matched.length === 0) {
+ var map = new Map();
+ for (j = 0; j < length; j += 1) {
+ var k = get_key(array[j], j);
+ if (map.has(k)) {
+ k = String(k);
+ if (k.startsWith('[object ')) k = null;
+ each_key_duplicate(String(j), String(map.get(k)), k);
+ }
+ map.set(k, j);
+ }
+ }
+
prev = start.prev;
var a = matched[0];
diff --git a/packages/svelte/tests/runtime-legacy/samples/keyed-each-dev-unique-prod/_config.js b/packages/svelte/tests/runtime-legacy/samples/keyed-each-dev-unique-prod/_config.js
new file mode 100644
index 0000000000..2ad5c1b3ef
--- /dev/null
+++ b/packages/svelte/tests/runtime-legacy/samples/keyed-each-dev-unique-prod/_config.js
@@ -0,0 +1,12 @@
+import { flushSync } from 'svelte';
+import { test } from '../../test';
+
+export default test({
+ test({ assert, target }) {
+ let button = target.querySelector('button');
+
+ button?.click();
+
+ assert.throws(flushSync, /each_key_duplicate/);
+ }
+});
diff --git a/packages/svelte/tests/runtime-legacy/samples/keyed-each-dev-unique-prod/main.svelte b/packages/svelte/tests/runtime-legacy/samples/keyed-each-dev-unique-prod/main.svelte
new file mode 100644
index 0000000000..38acbdee78
--- /dev/null
+++ b/packages/svelte/tests/runtime-legacy/samples/keyed-each-dev-unique-prod/main.svelte
@@ -0,0 +1,8 @@
+
+
+
+{#each data as d (d)}
+ {d}
+{/each}