fix: make Event phase constants writable/configurable to prevent TypeError - #57199
fix: make Event phase constants writable/configurable to prevent TypeError#57199IsaacIsrael wants to merge 3 commits into
Conversation
…Error 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 react#54732 Co-authored-by: Cursor <cursoragent@cursor.com>
5f3593f to
2dafc35
Compare
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 <cursoragent@cursor.com>
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 <cursoragent@cursor.com>
|
Thanks for digging into this, the crash in #54732 is real and the stack trace points right at it. I traced the fix and I think it clears the crash but changes the value of the instance constants in a way that might not be intended. Sharing what I found in case it is useful. RN compiles class fields in loose mode, so the instance declaration I checked this against the transpiled output with a small repro:
The existing tests would not catch this since they assert the static One option that fixes the crash and keeps A I might be missing context on why the readonly instance fields were kept, so let me know if there is a Flow reason |
Summary
Fixes #54732
The
Eventclass insrc/private/webapis/dom/events/Event.jsdefinesNONE,CAPTURING_PHASE,AT_TARGET, andBUBBLING_PHASEas bothreadonlyinstance fields and viaObject.definePropertywithoutwritable/configurableflags. When Hermes compiles these class fields, they become non-writable/non-configurable properties, causing aTypeErrorat instantiation time:This crashes whenever a WebSocket event fires (Metro dev connection, push notifications), and the unhandled
TypeErrorpropagates into any concurrent Promise chain — breakingfetch()uploads and other network operations.Changes
Remove
readonlyfrom instance-level field declarations — the static properties are inherited via the prototype chain automatically, so explicit readonly instance declarations are unnecessary and cause the Hermes conflict.Add
writable: true, configurable: trueto all 8Object.definePropertycalls — allowsevent-target-shim(used byabort-controller/fetch()) to redefine these properties when needed.Replace
Event.NONEinitializer with literal0— the[EVENT_PHASE_KEY]field initializer was referencingEvent.NONEbeforeObject.definePropertydefines it at the bottom of the file.Changelog:
[GENERAL] [FIXED] - Fix TypeError "Cannot assign to read-only property 'NONE'" in Event class when using New Architecture with Hermes
Test Plan
fetch()request or open a WebSocket connectionTypeError: Cannot assign to read-only property 'NONE'is thrownevent.NONE === 0,event.CAPTURING_PHASE === 1,event.AT_TARGET === 2,event.BUBBLING_PHASE === 3still hold on Event instances