diff --git a/CHANGELOG.md b/CHANGELOG.md
index cef7c34a3d..8e2b73a199 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@
* Fix tracking of dependencies of compound assignments in reactive statements ([#3634](https://github.com/sveltejs/svelte/issues/3634))
* Flush changes in newly attached block when using `{#await}` ([#3660](https://github.com/sveltejs/svelte/issues/3660))
* Throw exception immediately when calling `createEventDispatcher()` after component instantiation ([#3667](https://github.com/sveltejs/svelte/pull/3667))
+* Fix error resulting from trying to set a read-only property when spreading element attributes ([#3681](https://github.com/sveltejs/svelte/issues/3681))
## 3.12.1
diff --git a/src/runtime/internal/dom.ts b/src/runtime/internal/dom.ts
index 58a0d0729a..1c904fe2a3 100644
--- a/src/runtime/internal/dom.ts
+++ b/src/runtime/internal/dom.ts
@@ -90,10 +90,12 @@ export function attr(node: Element, attribute: string, value?: string) {
}
export function set_attributes(node: Element & ElementCSSInlineStyle, attributes: { [x: string]: string }) {
+ // @ts-ignore
+ const descriptors = Object.getOwnPropertyDescriptors(node.__proto__);
for (const key in attributes) {
if (key === 'style') {
node.style.cssText = attributes[key];
- } else if (key in node) {
+ } else if (descriptors[key] && descriptors[key].set) {
node[key] = attributes[key];
} else {
attr(node, key, attributes[key]);
diff --git a/test/runtime/samples/spread-element-readonly/_config.js b/test/runtime/samples/spread-element-readonly/_config.js
new file mode 100644
index 0000000000..1d349fd76f
--- /dev/null
+++ b/test/runtime/samples/spread-element-readonly/_config.js
@@ -0,0 +1,9 @@
+export default {
+ skip_if_ssr: true, // DOM and SSR output is different, a separate SSR test exists
+ html: ``,
+
+ test({ assert, target }) {
+ const div = target.querySelector('input');
+ assert.equal(div.value, 'bar');
+ }
+};
diff --git a/test/runtime/samples/spread-element-readonly/main.svelte b/test/runtime/samples/spread-element-readonly/main.svelte
new file mode 100644
index 0000000000..fc8c849396
--- /dev/null
+++ b/test/runtime/samples/spread-element-readonly/main.svelte
@@ -0,0 +1,9 @@
+
+
+
diff --git a/test/server-side-rendering/samples/spread-attributes/_expected.html b/test/server-side-rendering/samples/spread-attributes/_expected.html
new file mode 100644
index 0000000000..b78eafb8f4
--- /dev/null
+++ b/test/server-side-rendering/samples/spread-attributes/_expected.html
@@ -0,0 +1 @@
+
diff --git a/test/server-side-rendering/samples/spread-attributes/main.svelte b/test/server-side-rendering/samples/spread-attributes/main.svelte
new file mode 100644
index 0000000000..fc8c849396
--- /dev/null
+++ b/test/server-side-rendering/samples/spread-attributes/main.svelte
@@ -0,0 +1,9 @@
+
+
+