diff --git a/.changeset/fresh-chicken-itch.md b/.changeset/fresh-chicken-itch.md
new file mode 100644
index 0000000000..95120e1591
--- /dev/null
+++ b/.changeset/fresh-chicken-itch.md
@@ -0,0 +1,5 @@
+---
+'svelte': patch
+---
+
+fix: never mark a child effect root as inert
diff --git a/packages/svelte/src/internal/client/reactivity/effects.js b/packages/svelte/src/internal/client/reactivity/effects.js
index ea8a4b645e..0fad074e6f 100644
--- a/packages/svelte/src/internal/client/reactivity/effects.js
+++ b/packages/svelte/src/internal/client/reactivity/effects.js
@@ -654,16 +654,22 @@ function pause_children(effect, transitions, local) {
while (child !== null) {
var sibling = child.next;
- var transparent =
- (child.f & EFFECT_TRANSPARENT) !== 0 ||
- // If this is a branch effect without a block effect parent,
- // it means the parent block effect was pruned. In that case,
- // transparency information was transferred to the branch effect.
- ((child.f & BRANCH_EFFECT) !== 0 && (effect.f & BLOCK_EFFECT) !== 0);
- // TODO we don't need to call pause_children recursively with a linked list in place
- // it's slightly more involved though as we have to account for `transparent` changing
- // through the tree.
- pause_children(child, transitions, transparent ? local : false);
+
+ // If this child is a root effect, then it will become an independent root when its parent
+ // is destroyed, it should therefore not become inert nor partake in transitions.
+ if ((child.f & ROOT_EFFECT) === 0) {
+ var transparent =
+ (child.f & EFFECT_TRANSPARENT) !== 0 ||
+ // If this is a branch effect without a block effect parent,
+ // it means the parent block effect was pruned. In that case,
+ // transparency information was transferred to the branch effect.
+ ((child.f & BRANCH_EFFECT) !== 0 && (effect.f & BLOCK_EFFECT) !== 0);
+ // TODO we don't need to call pause_children recursively with a linked list in place
+ // it's slightly more involved though as we have to account for `transparent` changing
+ // through the tree.
+ pause_children(child, transitions, transparent ? local : false);
+ }
+
child = sibling;
}
}
diff --git a/packages/svelte/tests/runtime-runes/samples/effect-root-6/Child.svelte b/packages/svelte/tests/runtime-runes/samples/effect-root-6/Child.svelte
new file mode 100644
index 0000000000..110ad82b0d
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/effect-root-6/Child.svelte
@@ -0,0 +1,14 @@
+
diff --git a/packages/svelte/tests/runtime-runes/samples/effect-root-6/_config.js b/packages/svelte/tests/runtime-runes/samples/effect-root-6/_config.js
new file mode 100644
index 0000000000..e4077c6c27
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/effect-root-6/_config.js
@@ -0,0 +1,14 @@
+import { flushSync } from 'svelte';
+import { test } from '../../test';
+
+// Test that $effect.root continues to be operational after its parent effect has been destroyed
+export default test({
+ test({ assert, target, logs }) {
+ const [hide, increment] = target.querySelectorAll('button');
+
+ hide.click();
+ flushSync();
+ increment.click();
+ assert.deepEqual(logs, ['count', 1, 'double', 2]);
+ }
+});
diff --git a/packages/svelte/tests/runtime-runes/samples/effect-root-6/main.svelte b/packages/svelte/tests/runtime-runes/samples/effect-root-6/main.svelte
new file mode 100644
index 0000000000..254cddeb5b
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/effect-root-6/main.svelte
@@ -0,0 +1,15 @@
+
+
+
+
+{#if show}
+
+{/if}