diff --git a/.changeset/wild-chairs-build.md b/.changeset/wild-chairs-build.md
new file mode 100644
index 0000000000..494a3d70c5
--- /dev/null
+++ b/.changeset/wild-chairs-build.md
@@ -0,0 +1,5 @@
+---
+'svelte': patch
+---
+
+breaking: state mutations inside the template are no longer allowed
diff --git a/documentation/docs/98-reference/.generated/client-errors.md b/documentation/docs/98-reference/.generated/client-errors.md
index 4e7016b337..d6bd276de7 100644
--- a/documentation/docs/98-reference/.generated/client-errors.md
+++ b/documentation/docs/98-reference/.generated/client-errors.md
@@ -125,5 +125,5 @@ Reading state that was created inside the same derived is forbidden. Consider us
### state_unsafe_mutation
```
-Updating state inside a derived or logic block expression is forbidden. If the value should not be reactive, declare it without `$state`
+Updating state inside a derived or a template expression is forbidden. If the value should not be reactive, declare it without `$state`
```
diff --git a/packages/svelte/messages/client-errors/errors.md b/packages/svelte/messages/client-errors/errors.md
index 570a384d7c..954214cb81 100644
--- a/packages/svelte/messages/client-errors/errors.md
+++ b/packages/svelte/messages/client-errors/errors.md
@@ -82,4 +82,4 @@
## state_unsafe_mutation
-> Updating state inside a derived or logic block expression is forbidden. If the value should not be reactive, declare it without `$state`
+> Updating state inside a derived or a template expression is forbidden. If the value should not be reactive, declare it without `$state`
diff --git a/packages/svelte/src/internal/client/errors.js b/packages/svelte/src/internal/client/errors.js
index a0f33fb784..2a8f0e8914 100644
--- a/packages/svelte/src/internal/client/errors.js
+++ b/packages/svelte/src/internal/client/errors.js
@@ -343,12 +343,12 @@ export function state_unsafe_local_read() {
}
/**
- * Updating state inside a derived or logic block expression is forbidden. If the value should not be reactive, declare it without `$state`
+ * Updating state inside a derived or a template expression is forbidden. If the value should not be reactive, declare it without `$state`
* @returns {never}
*/
export function state_unsafe_mutation() {
if (DEV) {
- const error = new Error(`state_unsafe_mutation\nUpdating state inside a derived or logic block expression is forbidden. If the value should not be reactive, declare it without \`$state\``);
+ const error = new Error(`state_unsafe_mutation\nUpdating state inside a derived or a template expression is forbidden. If the value should not be reactive, declare it without \`$state\``);
error.name = 'Svelte error';
throw error;
diff --git a/packages/svelte/src/internal/client/reactivity/effects.js b/packages/svelte/src/internal/client/reactivity/effects.js
index ba17b8d5aa..193c6df145 100644
--- a/packages/svelte/src/internal/client/reactivity/effects.js
+++ b/packages/svelte/src/internal/client/reactivity/effects.js
@@ -326,7 +326,7 @@ export function template_effect(fn) {
value: '{expression}'
});
}
- return render_effect(fn);
+ return block(fn);
}
/**
diff --git a/packages/svelte/tests/runtime-runes/samples/side-effect-template/_config.js b/packages/svelte/tests/runtime-runes/samples/side-effect-template/_config.js
new file mode 100644
index 0000000000..b17c83849f
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/side-effect-template/_config.js
@@ -0,0 +1,17 @@
+import { flushSync } from 'svelte';
+import { test } from '../../test';
+
+export default test({
+ compileOptions: {
+ dev: true
+ },
+
+ test({ assert, target }) {
+ const button = target.querySelector('button');
+
+ assert.throws(() => {
+ button?.click();
+ flushSync();
+ }, /state_unsafe_mutation/);
+ }
+});
diff --git a/packages/svelte/tests/runtime-runes/samples/side-effect-template/main.svelte b/packages/svelte/tests/runtime-runes/samples/side-effect-template/main.svelte
new file mode 100644
index 0000000000..0a53a08673
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/side-effect-template/main.svelte
@@ -0,0 +1,6 @@
+
+
+
+{JSON.stringify(items.sort())}
diff --git a/packages/svelte/tests/runtime-runes/samples/store-unsubscribe-not-referenced-after/main.svelte b/packages/svelte/tests/runtime-runes/samples/store-unsubscribe-not-referenced-after/main.svelte
index 5f8b19f4c7..e097c639f0 100644
--- a/packages/svelte/tests/runtime-runes/samples/store-unsubscribe-not-referenced-after/main.svelte
+++ b/packages/svelte/tests/runtime-runes/samples/store-unsubscribe-not-referenced-after/main.svelte
@@ -1,4 +1,5 @@