From 2dafc35ccb2717c53a38826b2b207864b35b7360 Mon Sep 17 00:00:00 2001 From: Isaac Israel Date: Sun, 14 Jun 2026 16:52:03 +0300 Subject: [PATCH 1/3] fix: make Event phase constants writable/configurable to prevent TypeError The Event class defines NONE, CAPTURING_PHASE, AT_TARGET, BUBBLING_PHASE as readonly instance fields and via Object.defineProperty without writable/configurable flags. Hermes compiles these as non-writable, causing TypeError at instantiation: Cannot assign to read-only property NONE. This crashes on WebSocket events and propagates into fetch uploads. Fix: remove readonly from instance fields, add writable+configurable to Object.defineProperty calls, replace Event.NONE initializer with literal 0. Fixes #54732 Co-authored-by: Cursor --- .../src/private/webapis/dom/events/Event.js | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/packages/react-native/src/private/webapis/dom/events/Event.js b/packages/react-native/src/private/webapis/dom/events/Event.js index 4b161026426e..fbc2c90d3b15 100644 --- a/packages/react-native/src/private/webapis/dom/events/Event.js +++ b/packages/react-native/src/private/webapis/dom/events/Event.js @@ -50,11 +50,6 @@ export default class Event { static readonly AT_TARGET: 2; static readonly BUBBLING_PHASE: 3; - readonly NONE: 0; - readonly CAPTURING_PHASE: 1; - readonly AT_TARGET: 2; - readonly BUBBLING_PHASE: 3; - _bubbles: boolean; _cancelable: boolean; _composed: boolean; @@ -70,7 +65,7 @@ export default class Event { [CURRENT_TARGET_KEY]: EventTarget | null = null; // $FlowExpectedError[unsupported-syntax] - [EVENT_PHASE_KEY]: boolean = Event.NONE; + [EVENT_PHASE_KEY]: boolean = 0; // $FlowExpectedError[unsupported-syntax] [IN_PASSIVE_LISTENER_FLAG_KEY]: boolean = false; @@ -193,48 +188,64 @@ export default class Event { // $FlowExpectedError[cannot-write] Object.defineProperty(Event, 'NONE', { + writable: true, + configurable: true, enumerable: true, value: 0, }); // $FlowExpectedError[cannot-write] Object.defineProperty(Event.prototype, 'NONE', { + writable: true, + configurable: true, enumerable: true, value: 0, }); // $FlowExpectedError[cannot-write] Object.defineProperty(Event, 'CAPTURING_PHASE', { + writable: true, + configurable: true, enumerable: true, value: 1, }); // $FlowExpectedError[cannot-write] Object.defineProperty(Event.prototype, 'CAPTURING_PHASE', { + writable: true, + configurable: true, enumerable: true, value: 1, }); // $FlowExpectedError[cannot-write] Object.defineProperty(Event, 'AT_TARGET', { + writable: true, + configurable: true, enumerable: true, value: 2, }); // $FlowExpectedError[cannot-write] Object.defineProperty(Event.prototype, 'AT_TARGET', { + writable: true, + configurable: true, enumerable: true, value: 2, }); // $FlowExpectedError[cannot-write] Object.defineProperty(Event, 'BUBBLING_PHASE', { + writable: true, + configurable: true, enumerable: true, value: 3, }); // $FlowExpectedError[cannot-write] Object.defineProperty(Event.prototype, 'BUBBLING_PHASE', { + writable: true, + configurable: true, enumerable: true, value: 3, }); From a0d70aa6b4aff8bb006ef545df1b6c0bd8198c16 Mon Sep 17 00:00:00 2001 From: Isaac Israel Date: Mon, 15 Jun 2026 13:08:20 +0300 Subject: [PATCH 2/3] fix: restore instance-level Event phase declarations without readonly Flow needs the instance-level field declarations (NONE, CAPTURING_PHASE, AT_TARGET, BUBBLING_PHASE) to know these properties exist on Event instances. The previous commit removed them entirely, causing 12 Flow prop-missing errors. This restores them without the `readonly` modifier so Hermes won't create non-writable properties that conflict with the Object.defineProperty calls. Co-authored-by: Cursor --- .../react-native/src/private/webapis/dom/events/Event.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/react-native/src/private/webapis/dom/events/Event.js b/packages/react-native/src/private/webapis/dom/events/Event.js index fbc2c90d3b15..bd0ede757506 100644 --- a/packages/react-native/src/private/webapis/dom/events/Event.js +++ b/packages/react-native/src/private/webapis/dom/events/Event.js @@ -50,6 +50,11 @@ export default class Event { static readonly AT_TARGET: 2; static readonly BUBBLING_PHASE: 3; + NONE: 0; + CAPTURING_PHASE: 1; + AT_TARGET: 2; + BUBBLING_PHASE: 3; + _bubbles: boolean; _cancelable: boolean; _composed: boolean; From fa3ec585e047811834cbc4e8dee40c23bb89fcd0 Mon Sep 17 00:00:00 2001 From: Isaac Israel Date: Mon, 15 Jun 2026 13:18:38 +0300 Subject: [PATCH 3/3] fix: keep readonly on instance Event phase declarations for Flow The instance-level declarations need `readonly` to match their literal types (0, 1, 2, 3). Without readonly, Flow treats them as invariant and rejects the Object.defineProperty value assignments as incompatible-type. The readonly annotation is type-level only (stripped at runtime); the actual runtime fix is writable+configurable on Object.defineProperty. Co-authored-by: Cursor --- .../react-native/src/private/webapis/dom/events/Event.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/react-native/src/private/webapis/dom/events/Event.js b/packages/react-native/src/private/webapis/dom/events/Event.js index bd0ede757506..c392e5fd1af2 100644 --- a/packages/react-native/src/private/webapis/dom/events/Event.js +++ b/packages/react-native/src/private/webapis/dom/events/Event.js @@ -50,10 +50,10 @@ export default class Event { static readonly AT_TARGET: 2; static readonly BUBBLING_PHASE: 3; - NONE: 0; - CAPTURING_PHASE: 1; - AT_TARGET: 2; - BUBBLING_PHASE: 3; + readonly NONE: 0; + readonly CAPTURING_PHASE: 1; + readonly AT_TARGET: 2; + readonly BUBBLING_PHASE: 3; _bubbles: boolean; _cancelable: boolean;