+{/if}
From 890399ba94318382822aff7646914cd80887e59b Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 21 Oct 2025 12:36:13 +0000
Subject: [PATCH 3/3] Fix: Don't wrap await inside @const async functions with
save
The issue was that `is_reactive_expression` was returning true for all awaits inside @const tags because `in_derived` was set to true. This caused awaits inside async functions assigned to @const to be incorrectly pickled with $.save(), breaking reactivity.
The fix checks if there's a function in the path between the await and any reactive context. If there's a reactive rune call ($derived, $effect, etc.) between the function and the await, it's still considered reactive. Otherwise, it's not.
This preserves the correct behavior for $derived with await inside async functions while fixing the @const async function case.
Co-authored-by: dummdidumm <5968653+dummdidumm@users.noreply.github.com>
---
.../2-analyze/visitors/AwaitExpression.js | 27 +++++++++++++++----
1 file changed, 22 insertions(+), 5 deletions(-)
diff --git a/packages/svelte/src/compiler/phases/2-analyze/visitors/AwaitExpression.js b/packages/svelte/src/compiler/phases/2-analyze/visitors/AwaitExpression.js
index 90186235708a..2464f7157dbf 100644
--- a/packages/svelte/src/compiler/phases/2-analyze/visitors/AwaitExpression.js
+++ b/packages/svelte/src/compiler/phases/2-analyze/visitors/AwaitExpression.js
@@ -53,10 +53,6 @@ export function AwaitExpression(node, context) {
* @param {boolean} in_derived
*/
export function is_reactive_expression(path, in_derived) {
- if (in_derived) {
- return true;
- }
-
let i = path.length;
while (i--) {
@@ -67,6 +63,27 @@ export function is_reactive_expression(path, in_derived) {
parent.type === 'FunctionExpression' ||
parent.type === 'FunctionDeclaration'
) {
+ // Check if there's a reactive rune call (like $derived) between this function and the await
+ for (let j = i + 1; j < path.length; j++) {
+ const node = path[j];
+ // @ts-expect-error
+ if (node.metadata) {
+ // There's a reactive expression between the function and the await
+ return true;
+ }
+ // Also check for $derived, $effect, etc. calls
+ if (
+ node.type === 'CallExpression' &&
+ node.callee?.type === 'Identifier' &&
+ (node.callee.name === '$derived' ||
+ node.callee.name === '$effect' ||
+ node.callee.name === '$inspect')
+ ) {
+ // This is a reactive rune call
+ return true;
+ }
+ }
+ // No reactive expression found between function and await
return false;
}
@@ -76,7 +93,7 @@ export function is_reactive_expression(path, in_derived) {
}
}
- return false;
+ return in_derived;
}
/**