Skip to content

In onblur handler: state_unsafe_mutation Updating state inside a derived or logic block expression is forbidden [svelte 5 issue]Β #13684

@kyle-leonhard

Description

@kyle-leonhard

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.269

Severity

blocking an upgrade

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions