From fa226778b00486d60dbc7e889838ba199fa668ee Mon Sep 17 00:00:00 2001 From: asphum Date: Sun, 16 Aug 2026 18:07:39 +0700 Subject: [PATCH] fix: coerce symbols to empty string in set_text Under experimental.async, $bindable can surface Symbol(UNINITIALIZED). set_text previously passed symbols through and threw when setting nodeValue. --- .changeset/set-text-symbol-guard.md | 9 +++++++++ packages/svelte/src/internal/client/render.js | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 .changeset/set-text-symbol-guard.md diff --git a/.changeset/set-text-symbol-guard.md b/.changeset/set-text-symbol-guard.md new file mode 100644 index 0000000000..559e41897e --- /dev/null +++ b/.changeset/set-text-symbol-guard.md @@ -0,0 +1,9 @@ +--- +'svelte': patch +--- + +fix: coerce symbols to empty string in `set_text` + +Under `experimental.async`, `$bindable` props can briefly surface `Symbol(UNINITIALIZED)`. +`set_text` treated symbols as already-stringifiable values, then threw when assigning +`text.nodeValue = \`${str}\``. Treat symbols like nullish values so text nodes stay stable. diff --git a/packages/svelte/src/internal/client/render.js b/packages/svelte/src/internal/client/render.js index 50832fb3ff..bacd8927ee 100644 --- a/packages/svelte/src/internal/client/render.js +++ b/packages/svelte/src/internal/client/render.js @@ -45,7 +45,7 @@ export function set_should_intro(value) { */ export function set_text(text, value) { // For objects, we apply string coercion (which might make things like $state array references in the template reactive) before diffing - var str = value == null ? '' : typeof value === 'object' ? `${value}` : value; + var str = value == null || typeof value === 'symbol' ? '' : typeof value === 'object' ? `${value}` : value; // prettier-ignore if (str !== (/** @type {any} */ (text)[TEXT_CACHE] ??= text.nodeValue)) { /** @type {any} */ (text)[TEXT_CACHE] = str;