diff --git a/.changeset/olive-mice-fix.md b/.changeset/olive-mice-fix.md
new file mode 100644
index 0000000000..b3548bd11f
--- /dev/null
+++ b/.changeset/olive-mice-fix.md
@@ -0,0 +1,5 @@
+---
+"svelte": patch
+---
+
+fix: improve handling of unowned derived signals
diff --git a/packages/svelte/src/internal/client/reactivity/deriveds.js b/packages/svelte/src/internal/client/reactivity/deriveds.js
index 24806084ae..b258e486ba 100644
--- a/packages/svelte/src/internal/client/reactivity/deriveds.js
+++ b/packages/svelte/src/internal/client/reactivity/deriveds.js
@@ -41,7 +41,7 @@ export function derived(fn) {
/** @type {import('#client').DerivedDebug} */ (signal).inspect = new Set();
}
- if (current_reaction !== null) {
+ if (current_reaction !== null && (current_reaction.f & DERIVED) !== 0) {
if (current_reaction.deriveds === null) {
current_reaction.deriveds = [signal];
} else {
diff --git a/packages/svelte/tests/runtime-runes/samples/derived-unowned-3/_config.js b/packages/svelte/tests/runtime-runes/samples/derived-unowned-3/_config.js
new file mode 100644
index 0000000000..3c1f70999f
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/derived-unowned-3/_config.js
@@ -0,0 +1,30 @@
+import { flushSync } from 'svelte';
+import { test } from '../../test';
+
+export default test({
+ async test({ assert, target }) {
+ let [btn1, btn2] = target.querySelectorAll('button');
+
+ flushSync(() => {
+ btn1.click();
+ });
+
+ flushSync(() => {
+ btn2.click();
+ });
+
+ assert.htmlEqual(
+ target.innerHTML,
+ `\nneighba\nneighba`
+ );
+
+ flushSync(() => {
+ btn2.click();
+ });
+
+ assert.htmlEqual(
+ target.innerHTML,
+ `\nzeeba\nzeeba`
+ );
+ }
+});
diff --git a/packages/svelte/tests/runtime-runes/samples/derived-unowned-3/main.svelte b/packages/svelte/tests/runtime-runes/samples/derived-unowned-3/main.svelte
new file mode 100644
index 0000000000..7c32ed0513
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/derived-unowned-3/main.svelte
@@ -0,0 +1,49 @@
+
+
+
+
+{model.name}
+{model.data.name}