From 6076bab730ee7752898926ac6e10bbaf5e665a22 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 17 Sep 2025 19:30:45 -0400 Subject: [PATCH] fix: issue `state_proxy_unmount` warning when unmounting a state proxy (#16747) * fix: issue `state_proxy_unmount` warning when unmounting a state proxy * regenerate --- .changeset/fuzzy-pillows-tell.md | 5 +++++ .../.generated/client-warnings.md | 21 +++++++++++++++++++ .../messages/client-warnings/warnings.md | 19 +++++++++++++++++ packages/svelte/src/internal/client/render.js | 8 +++++-- .../svelte/src/internal/client/warnings.js | 11 ++++++++++ 5 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 .changeset/fuzzy-pillows-tell.md diff --git a/.changeset/fuzzy-pillows-tell.md b/.changeset/fuzzy-pillows-tell.md new file mode 100644 index 0000000000..9d2e54ac64 --- /dev/null +++ b/.changeset/fuzzy-pillows-tell.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: issue `state_proxy_unmount` warning when unmounting a state proxy diff --git a/documentation/docs/98-reference/.generated/client-warnings.md b/documentation/docs/98-reference/.generated/client-warnings.md index 6f1d677fe9..c95ace2229 100644 --- a/documentation/docs/98-reference/.generated/client-warnings.md +++ b/documentation/docs/98-reference/.generated/client-warnings.md @@ -312,6 +312,27 @@ Reactive `$state(...)` proxies and the values they proxy have different identiti To resolve this, ensure you're comparing values where both values were created with `$state(...)`, or neither were. Note that `$state.raw(...)` will _not_ create a state proxy. +### state_proxy_unmount + +``` +Tried to unmount a state proxy, rather than a component +``` + +`unmount` was called with a state proxy: + +```js +import { mount, unmount } from 'svelte'; +import Component from './Component.svelte'; +let target = document.body; +// ---cut--- +let component = $state(mount(Component, { target })); + +// later... +unmount(component); +``` + +Avoid using `$state` here. If `component` _does_ need to be reactive for some reason, use `$state.raw` instead. + ### svelte_boundary_reset_noop ``` diff --git a/packages/svelte/messages/client-warnings/warnings.md b/packages/svelte/messages/client-warnings/warnings.md index 123c6833e6..9763c8df1a 100644 --- a/packages/svelte/messages/client-warnings/warnings.md +++ b/packages/svelte/messages/client-warnings/warnings.md @@ -272,6 +272,25 @@ To silence the warning, ensure that `value`: To resolve this, ensure you're comparing values where both values were created with `$state(...)`, or neither were. Note that `$state.raw(...)` will _not_ create a state proxy. +## state_proxy_unmount + +> Tried to unmount a state proxy, rather than a component + +`unmount` was called with a state proxy: + +```js +import { mount, unmount } from 'svelte'; +import Component from './Component.svelte'; +let target = document.body; +// ---cut--- +let component = $state(mount(Component, { target })); + +// later... +unmount(component); +``` + +Avoid using `$state` here. If `component` _does_ need to be reactive for some reason, use `$state.raw` instead. + ## svelte_boundary_reset_noop > A `` `reset` function only resets the boundary the first time it is called diff --git a/packages/svelte/src/internal/client/render.js b/packages/svelte/src/internal/client/render.js index 0910c6d06c..ecd22a1db6 100644 --- a/packages/svelte/src/internal/client/render.js +++ b/packages/svelte/src/internal/client/render.js @@ -30,7 +30,7 @@ import * as w from './warnings.js'; import * as e from './errors.js'; import { assign_nodes } from './dom/template.js'; import { is_passive_event } from '../../utils.js'; -import { COMMENT_NODE } from './constants.js'; +import { COMMENT_NODE, STATE_SYMBOL } from './constants.js'; import { boundary } from './dom/blocks/boundary.js'; /** @@ -316,7 +316,11 @@ export function unmount(component, options) { } if (DEV) { - w.lifecycle_double_unmount(); + if (STATE_SYMBOL in component) { + w.state_proxy_unmount(); + } else { + w.lifecycle_double_unmount(); + } } return Promise.resolve(); diff --git a/packages/svelte/src/internal/client/warnings.js b/packages/svelte/src/internal/client/warnings.js index dfa2a3752e..1081ef5861 100644 --- a/packages/svelte/src/internal/client/warnings.js +++ b/packages/svelte/src/internal/client/warnings.js @@ -224,6 +224,17 @@ export function state_proxy_equality_mismatch(operator) { } } +/** + * Tried to unmount a state proxy, rather than a component + */ +export function state_proxy_unmount() { + if (DEV) { + console.warn(`%c[svelte] state_proxy_unmount\n%cTried to unmount a state proxy, rather than a component\nhttps://svelte.dev/e/state_proxy_unmount`, bold, normal); + } else { + console.warn(`https://svelte.dev/e/state_proxy_unmount`); + } +} + /** * A `` `reset` function only resets the boundary the first time it is called */