-
-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Closed
Labels
Description
Describe the bug
A state_unsafe_mutation error is triggered when an onblur handler changes a store value used in a $derived call.
I'm not really sure what the absolute minimal example is or the cause, I'm kind of a svelte newbie. I reproduced the error in a more contrived way in a repl attached.
This is triggered when upgrading from 5.0.0-next.267 to 5.0.0-next.269. I'm fairly sure it's triggered by #13625
Reproduction
Hover and then click one of the buttons in the repl
App.svelte:
<script>
import {
writable,
} from "svelte/store";
import Component2 from "./Component2.svelte";
let highlighted = writable(null);
let indices = $state([1,2,3,4,5]);
function handleOnClick(index) {
console.log(`Deleting ${index}`);
delete indices[indices.findIndex((el) => el === index)];
}
</script>
{#each indices as index}
<Component2 {index} {highlighted} handleOnClick={() => {handleOnClick(index); }}></Component2>
{/each}
Component2.svelte:
<script>
const { index, highlighted, handleOnClick } = $props();
let elementt = $state();
let isHovered = $derived($highlighted === index);
function handleHighlight() {
$highlighted = index;
}
function handleUnhighlight() {
$highlighted = null;
}
</script>
<div><button
onmouseout={() => {
handleUnhighlight();
}}
onmouseover={() => {
handleHighlight();
}}
onblur={() => {
console.log("onblur row");
handleUnhighlight();
}}
onfocus={() => {
console.log("onfocus row");
handleHighlight();
}}
onclick={() => {
handleOnClick();
}}
bind:this={elementt}>
Row {index}, {isHovered}
</button></div>
Logs
Error: 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`
message:"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`"
stack:"Svelte error: state_unsafe_mutation\n" +
"Updating state inside a derived or logic block expression is forbidden. If the value should not be reactive, declare it without `$state`\n" +
" at state_unsafe_mutation (playground:output:244:18)\n" +
" at set (playground:output:339:4)\n" +
" at Array.eval (playground:output:3886:7)\n" +
" at Object.set (playground:output:4041:30)\n" +
" at store_set (playground:output:3905:9)\n" +
" at handleUnhighlight (playground:output:4119:4)\n" +
" at HTMLButtonElement.eval (playground:output:4135:4)\n" +
" at HTMLButtonElement.target_handler (playground:output:2675:20)\n" +
" at destroy_effect (playground:output:1408:10)\n" +
" at eval (playground:output:3352:5)"System Info
System:
OS: macOS 15.0.1
CPU: (16) arm64 Apple M3 Max
Memory: 16.74 GB / 64.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 22.9.0 - /opt/homebrew/bin/node
npm: 10.8.3 - /opt/homebrew/bin/npm
pnpm: 9.12.2 - /opt/homebrew/bin/pnpm
Browsers:
Chrome: 130.0.6723.59
Safari: 18.0.1
npmPackages:
svelte: 5.0.0-next.269 => 5.0.0-next.269Severity
blocking an upgrade
Azarattum