diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js
index 3a31c175f1..5f59b7aeac 100644
--- a/packages/svelte/src/internal/client/runtime.js
+++ b/packages/svelte/src/internal/client/runtime.js
@@ -664,15 +664,18 @@ function reconnect(derived) {
/**
* Removes the WAS_MARKED flag from the derived and its dependencies
- * @param {Derived} derived
+ * @param {Value} derived
*/
function remove_marked_flag(derived) {
- if ((derived.f & WAS_MARKED) === 0) return;
- derived.f ^= WAS_MARKED;
+ // We cannot stop at the first non-marked derived because batch_values can
+ // cause "holes" of unmarked deriveds in an otherwise marked graph
+ if ((derived.f & DERIVED) === 0) return;
+
+ derived.f &= ~WAS_MARKED;
// Only deriveds with dependencies can be marked
- for (const dep of /** @type {Value[]} */ (derived.deps)) {
- remove_marked_flag(/** @type {Derived} */ (dep));
+ for (const dep of /** @type {Value[]} */ (/** @type {Derived} */ (derived).deps)) {
+ remove_marked_flag(dep);
}
}
diff --git a/packages/svelte/tests/runtime-runes/samples/async-derived-in-multiple-effects/Component.svelte b/packages/svelte/tests/runtime-runes/samples/async-derived-in-multiple-effects/Component.svelte
new file mode 100644
index 0000000000..200778dc5b
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-derived-in-multiple-effects/Component.svelte
@@ -0,0 +1,27 @@
+
diff --git a/packages/svelte/tests/runtime-runes/samples/async-derived-in-multiple-effects/_config.js b/packages/svelte/tests/runtime-runes/samples/async-derived-in-multiple-effects/_config.js
new file mode 100644
index 0000000000..600e7f096b
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-derived-in-multiple-effects/_config.js
@@ -0,0 +1,18 @@
+import { tick } from 'svelte';
+import { test } from '../../test';
+
+export default test({
+ async test({ assert, target, logs }) {
+ const button = target.querySelector('button');
+
+ button?.click();
+ await tick();
+ // TODO this is wrong: it should be [5]
+ assert.deepEqual(logs, [4]);
+
+ button?.click();
+ await tick();
+ // TODO this is wrong: it should be [5, 7]
+ assert.deepEqual(logs, [4, 7]);
+ }
+});
diff --git a/packages/svelte/tests/runtime-runes/samples/async-derived-in-multiple-effects/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-derived-in-multiple-effects/main.svelte
new file mode 100644
index 0000000000..bd82e35a3b
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-derived-in-multiple-effects/main.svelte
@@ -0,0 +1,19 @@
+
+
+
+ {await new Promise((r) => {
+ // long enough for the test to do all its other stuff while this is pending
+ setTimeout(r, 10);
+ })}
+ {#snippet pending()}{/snippet}
+
+
+
+
+{#if count > 0}
+
+{/if}