diff --git a/.changeset/fix-derived-teardown-eager-path.md b/.changeset/fix-derived-teardown-eager-path.md
new file mode 100644
index 0000000000..a781ee2f27
--- /dev/null
+++ b/.changeset/fix-derived-teardown-eager-path.md
@@ -0,0 +1,5 @@
+---
+"svelte": patch
+---
+
+fix: ensure `$derived` returns pre-change value during teardown in eager block effects path
diff --git a/packages/svelte/src/internal/client/reactivity/batch.js b/packages/svelte/src/internal/client/reactivity/batch.js
index 7d14b80519..8d58c5c830 100644
--- a/packages/svelte/src/internal/client/reactivity/batch.js
+++ b/packages/svelte/src/internal/client/reactivity/batch.js
@@ -1111,8 +1111,6 @@ function flush_queued_effects(effects) {
// If update_effect() has a flushSync() in it, we may have flushed another flush_queued_effects(),
// which already handled this logic and did set eager_block_effects to null.
if (eager_block_effects?.size > 0) {
- old_values.clear();
-
for (const e of eager_block_effects) {
// Skip eager effects that have already been unmounted
if ((e.f & (DESTROYED | INERT)) !== 0) continue;
diff --git a/packages/svelte/tests/runtime-runes/samples/derived-old-value-eager-unmount/Child.svelte b/packages/svelte/tests/runtime-runes/samples/derived-old-value-eager-unmount/Child.svelte
new file mode 100644
index 0000000000..551a75855a
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/derived-old-value-eager-unmount/Child.svelte
@@ -0,0 +1,25 @@
+
+
+a: {a}
+b: {b}
+c: {c}
+d: {d}
diff --git a/packages/svelte/tests/runtime-runes/samples/derived-old-value-eager-unmount/_config.js b/packages/svelte/tests/runtime-runes/samples/derived-old-value-eager-unmount/_config.js
new file mode 100644
index 0000000000..9433ded65c
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/derived-old-value-eager-unmount/_config.js
@@ -0,0 +1,14 @@
+import { flushSync } from 'svelte';
+import { test, ok } from '../../test';
+
+export default test({
+ async test({ assert, logs, target }) {
+ const button = target.querySelector('button');
+ ok(button);
+
+ flushSync(() => button.click());
+
+ // All four teardowns should see the pre-change derived value (2), not the post-change value (10)
+ assert.deepEqual(logs, ['effect.pre', 2, 'attach', 2, 'effect', 2, 'onDestroy', 2]);
+ }
+});
diff --git a/packages/svelte/tests/runtime-runes/samples/derived-old-value-eager-unmount/main.svelte b/packages/svelte/tests/runtime-runes/samples/derived-old-value-eager-unmount/main.svelte
new file mode 100644
index 0000000000..19c52409ed
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/derived-old-value-eager-unmount/main.svelte
@@ -0,0 +1,17 @@
+
+
+
+
+{#if count < 5}
+
+{/if}
diff --git a/packages/svelte/tests/runtime-runes/samples/onmount-prop-access/_config.js b/packages/svelte/tests/runtime-runes/samples/onmount-prop-access/_config.js
index 0d24e265d3..a7727343eb 100644
--- a/packages/svelte/tests/runtime-runes/samples/onmount-prop-access/_config.js
+++ b/packages/svelte/tests/runtime-runes/samples/onmount-prop-access/_config.js
@@ -2,6 +2,6 @@ import { test } from '../../test';
export default test({
async test({ assert, logs }) {
- assert.deepEqual(logs, [1]);
+ assert.deepEqual(logs, [0]);
}
});