diff --git a/.changeset/five-birds-check.md b/.changeset/five-birds-check.md
new file mode 100644
index 0000000000..edf46bff53
--- /dev/null
+++ b/.changeset/five-birds-check.md
@@ -0,0 +1,5 @@
+---
+'svelte': patch
+---
+
+fix: widen ownership upon property access if necessary
diff --git a/packages/svelte/src/internal/client/proxy.js b/packages/svelte/src/internal/client/proxy.js
index 48d6df4d30..13367ec2fd 100644
--- a/packages/svelte/src/internal/client/proxy.js
+++ b/packages/svelte/src/internal/client/proxy.js
@@ -131,6 +131,22 @@ export function proxy(value, parent = null, prev) {
if (s !== undefined) {
var v = get(s);
+
+ // In case of something like `foo = bar.map(...)`, foo would have ownership
+ // of the array itself, while the individual items would have ownership
+ // of the component that created the proxy. That means if we later do
+ // `foo[0].baz = 42`, we could get a false-positive ownership violation,
+ // since the two proxies are not connected to each other via the parent
+ // relationship. For this reason, we need to widen the ownership of the
+ // children upon access when we detect they are not connected.
+ if (DEV) {
+ /** @type {ProxyMetadata | undefined} */
+ var prop_metadata = v?.[STATE_SYMBOL_METADATA];
+ if (prop_metadata && prop_metadata?.parent !== metadata) {
+ widen_ownership(metadata, prop_metadata);
+ }
+ }
+
return v === UNINITIALIZED ? undefined : v;
}
diff --git a/packages/svelte/tests/runtime-runes/samples/non-local-mutation-with-binding-7/Component1.svelte b/packages/svelte/tests/runtime-runes/samples/non-local-mutation-with-binding-7/Component1.svelte
new file mode 100644
index 0000000000..1db07ddbd0
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/non-local-mutation-with-binding-7/Component1.svelte
@@ -0,0 +1,13 @@
+
+
+
diff --git a/packages/svelte/tests/runtime-runes/samples/non-local-mutation-with-binding-7/Component2.svelte b/packages/svelte/tests/runtime-runes/samples/non-local-mutation-with-binding-7/Component2.svelte
new file mode 100644
index 0000000000..8d63b9e9a9
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/non-local-mutation-with-binding-7/Component2.svelte
@@ -0,0 +1,7 @@
+
+
+{#if rows.length}
+
+{/if}
diff --git a/packages/svelte/tests/runtime-runes/samples/non-local-mutation-with-binding-7/_config.js b/packages/svelte/tests/runtime-runes/samples/non-local-mutation-with-binding-7/_config.js
new file mode 100644
index 0000000000..e766a946d0
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/non-local-mutation-with-binding-7/_config.js
@@ -0,0 +1,22 @@
+import { flushSync } from 'svelte';
+import { ok, test } from '../../test';
+
+// Tests that proxies widen ownership correctly even if not directly connected to each other
+export default test({
+ compileOptions: {
+ dev: true
+ },
+
+ test({ assert, target, warnings }) {
+ const input = target.querySelector('input');
+ ok(input);
+
+ input.checked = true;
+ input.dispatchEvent(new Event('input', { bubbles: true }));
+ flushSync();
+
+ assert.deepEqual(warnings, []);
+ },
+
+ warnings: []
+});
diff --git a/packages/svelte/tests/runtime-runes/samples/non-local-mutation-with-binding-7/main.svelte b/packages/svelte/tests/runtime-runes/samples/non-local-mutation-with-binding-7/main.svelte
new file mode 100644
index 0000000000..60a9b19a05
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/non-local-mutation-with-binding-7/main.svelte
@@ -0,0 +1,7 @@
+
+
+