Repository: sveltejs/svelte (JavaScript)

Issue:
`hydration_mismatch` when `pending` snippet is passed as prop to `<svelte:boundary>`
### Describe the bug

`hydration_mismatch` error shows up when passing the `pending` snippet as a prop to `<svelte:boundary>` instead of as a child.

I.e. this works

```svelte
<svelte:boundary>
  {@const _ = await new Promise((r) => setTimeout(r, 2000))}
  <p>Content has now loaded</p>

  {#snippet pending()}
    loading...
  {/snippet}
</svelte:boundary>
```

While this _does not_

```svelte
{#snippet pending()}
  loading...
{/snippet}

<svelte:boundary {pending}>
  {@const _ = await new Promise((r) => setTimeout(r, 2000))}
  <p>Content has now loaded</p>
</svelte:boundary>
```

Furthermore. The latter briefly shows `undefined` right after the pending snippet, which quickly disappears again.

### Reproduction

https://stackblitz.com/github/tinggaard/boundary-pending-prop

### Logs

```Shell
[svelte] hydration_mismatch
```

### System Info

```Shell
System:
    OS: Linux 6.16 Arch Linux
    CPU: (16) x64 AMD Ryzen 7 8845HS w/ Radeon 780M Graphics
    Memory: 14.68 GB / 27.15 GB
    Container: Yes
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 24.8.0 - /usr/bin/node
    npm: 11.6.1 - /usr/bin/npm
    pnpm: 10.17.1 - /usr/bin/pnpm
  Browsers:
    Brave Browser: 139.1.81.137
    Chromium: 140.0.7339.207
  npmPackages:
    @sveltejs/adapter-auto: ^6.1.1 => 6.1.1
    @sveltejs/kit: 2.43.8 => 2.43.8
    @sveltejs/vite-plugin-svelte: ^6.2.1 => 6.2.1
    svelte: ^5.39.8 => 5.39.8
    vite: ^7.1.9 => 7.1.9
```

### Severity

annoyance

### Additional Information

_No response_


Discussion:
I think this is actually a different error and I don't get how you are getting the `hydration_mismatch` error...when passing the `pending` snippet as a prop the generated `SSR` code looks like this

```ts
import 'svelte/internal/flags/async';
import * as $ from 'svelte/internal/server';

function pending($$renderer) {}

export default function App($$renderer) {
	if (pending) {
		$$renderer.push(`<!--[!-->${pending($$renderer)}<!--]-->`);
	} else {
		$$renderer.push(`<!--[-->`);

		{
			const x = (await $.save(Promise.resolve()))();
		}

		$$renderer.push(`<!--]-->`);
	}
}
```
which means it's actually failing to SSR because the `await` keywork is not inside an async function.

So SSR will throw an error but not an `hydration_mismatch` 🤔 
I see.
I am also getting an SSR error in the stackblitz environment, but when I run it locally, it shows no error, but rather the `hydration_mismatch` warning in the browser console.
Are you running the same exact code?
Yes.
```
git clone https://github.com/Tinggaard/boundary-pending-prop
cd boundary-pending-prop
pnpm install
pnpm dev
```

Does not create an error, but the warning described above
Ok i figured it out...it was using an old version of svelte (not that old) which didn't had the problem (but still had another issue that is solved by my PR)
Awesome! Thanks for investigating :)
I would like to reopen this issue, as the `hydration_mismatch` warning persists in version `5.39.12`.

Steps to reproduce:
```bash
git clone https://github.com/Tinggaard/boundary-pending-prop
cd boundary-pending-prop
git switch svelte/5.39.12
pnpm install
pnpm dev
```

Or on Stackblitz: https://stackblitz.com/github/tinggaard/boundary-pending-prop/tree/svelte/5.39.12
> I would like to reopen this issue...

Ping @paoloricciuti 
Yup I think we are pushing more comments than needed



Patch:
diff --git a/.changeset/happy-numbers-stick.md b/.changeset/happy-numbers-stick.md
new file mode 100644
index 000000000000..12fbd68ad85d
--- /dev/null
+++ b/.changeset/happy-numbers-stick.md
@@ -0,0 +1,5 @@
+---
+'svelte': patch
+---
+
+fix: add hydration markers in `pending` branch of SSR boundary
diff --git a/packages/svelte/src/compiler/phases/3-transform/server/visitors/SvelteBoundary.js b/packages/svelte/src/compiler/phases/3-transform/server/visitors/SvelteBoundary.js
index 41a18cf52da6..45f1b5aad2b3 100644
--- a/packages/svelte/src/compiler/phases/3-transform/server/visitors/SvelteBoundary.js
+++ b/packages/svelte/src/compiler/phases/3-transform/server/visitors/SvelteBoundary.js
@@ -49,7 +49,7 @@ export function SvelteBoundary(node, context) {
 			context.state.template.push(
 				b.if(
 					callee,
-					b.block([b.stmt(pending)]),
+					b.block(build_template([block_open_else, b.stmt(pending), block_close])),
 					b.block(build_template([block_open, statement, block_close]))
 				)
 			);


Test patch:
diff --git a/packages/svelte/tests/hydration/samples/boundary-pending-attribute/_config.js b/packages/svelte/tests/hydration/samples/boundary-pending-attribute/_config.js
new file mode 100644
index 000000000000..eec39eb84cef
--- /dev/null
+++ b/packages/svelte/tests/hydration/samples/boundary-pending-attribute/_config.js
@@ -0,0 +1,10 @@
+import { flushSync } from 'svelte';
+import { assert_ok, test } from '../../test';
+
+export default test({
+	compileOptions: {
+		experimental: {
+			async: true
+		}
+	}
+});
diff --git a/packages/svelte/tests/hydration/samples/boundary-pending-attribute/_expected.html b/packages/svelte/tests/hydration/samples/boundary-pending-attribute/_expected.html
new file mode 100644
index 000000000000..8b44c4cc91b9
--- /dev/null
+++ b/packages/svelte/tests/hydration/samples/boundary-pending-attribute/_expected.html
@@ -0,0 +1,1 @@
+<!--[--><!--[!--><!---->loading...<!--]--><!--]-->
\ No newline at end of file
diff --git a/packages/svelte/tests/hydration/samples/boundary-pending-attribute/main.svelte b/packages/svelte/tests/hydration/samples/boundary-pending-attribute/main.svelte
new file mode 100644
index 000000000000..15612dd27eac
--- /dev/null
+++ b/packages/svelte/tests/hydration/samples/boundary-pending-attribute/main.svelte
@@ -0,0 +1,8 @@
+{#snippet pending()}
+	loading...
+{/snippet}
+
+<svelte:boundary {pending}>
+	{@const data = await Promise.resolve("data")}
+	{data}
+</svelte:boundary>
\ No newline at end of file