Skip to content

fix(Settings): defer Platform lookup to fix circular dependency startup crash (#56967) - #57878

Open
SnowingFox wants to merge 1 commit into
react:mainfrom
SnowingFox:fix/issue-56967-settings-circular-dependency
Open

fix(Settings): defer Platform lookup to fix circular dependency startup crash (#56967)#57878
SnowingFox wants to merge 1 commit into
react:mainfrom
SnowingFox:fix/issue-56967-settings-circular-dependency

Conversation

@SnowingFox

Copy link
Copy Markdown
Contributor

Summary:

Fixes #56967.

Settings.js evaluated Platform.OS at module load time (a top-level if (Platform.OS === 'ios') branch after importing Platform from ../Utilities/Platform). When another module required Settings while Platform.ios.js / Platform.android.js was still mid-initialization (circular require — e.g. NativePlatformConstantsIOS being loaded by Platform.ios.js), the Platform export object was not yet populated, so Platform.OS dereferenced undefined and threw:

TypeError: Cannot read properties of undefined (reading 'OS')
  at Object.OS (Libraries/Settings/Settings.js:21:14)
  at require (.../Utilities/Platform.ios.js:13:1)

This fix defers the platform lookup: Platform is now required lazily inside getSettings() on the first method call, instead of at module load. The public API is unchanged (get / set / watchKeys / clearWatch still delegate to the iOS implementation on iOS and the fallback implementation elsewhere), matching the existing Settings.d.ts.

Changelog:

[GENERAL] [FIXED] - Defer Platform lookup in Settings.js to fix circular dependency startup crash

Test Plan:

Added packages/react-native/Libraries/Settings/__tests__/Settings-test.js (none existed) with 4 tests:

  1. the circular-dependency repro from the issue,
  2. lazy Platform access (Platform not touched at module load),
  3. iOS delegation (get/set/watchKeys/clearWatch call through to NativeSettingsManager),
  4. non-iOS fallback behavior.

RED — on the unmodified code, the circular-dependency test fails with exactly the reported bug:

● Settings › should not throw due to circular dependency during Platform initialization
  expect(received).not.toThrow()
  Error name:    "TypeError"
  Error message: "Cannot read properties of undefined (reading 'OS')"
        > 21 | if (Platform.OS === 'ios') {
             |              ^
  at Object.OS (packages/react-native/Libraries/Settings/Settings.js:21:14)
  at require (.../Libraries/Utilities/Platform.ios.js:13:1)
Test Suites: 1 failed, 1 total
Tests:       2 failed, 2 passed, 4 total

GREEN — after the fix:

PASS packages/react-native/Libraries/Settings/__tests__/Settings-test.js
  Settings
    ✓ should not throw due to circular dependency during Platform initialization
    ✓ defers accessing Platform until a method is first invoked
    ✓ delegates get/set/watchKeys/clearWatch to the iOS implementation
    ✓ uses the fallback implementation on non-iOS platforms
Test Suites: 1 passed, 1 total
Tests:       4 passed, 4 total

Regression check — Settings + Utilities suites (Platform lives in Libraries/Utilities):

PASS packages/react-native/Libraries/Settings/__tests__/Settings-test.js
PASS packages/react-native/Libraries/Utilities/__tests__/ReactNativeTestTools-test.js
PASS packages/react-native/Libraries/Utilities/__tests__/codegenNativeComponent-test.js
Test Suites: 3 passed, 3 total
Tests:       15 passed, 15 total

Also verified: eslint on the changed files exits clean (0 errors).

Summary:
Fixes react#56967. Settings.js evaluated Platform.OS at module load time, so
when another module required Settings while Platform was still
initializing (circular require), the Platform export was undefined and
reading Platform.OS threw "Cannot read properties of undefined (reading
'OS')". Defer the platform lookup: resolve Platform lazily inside
getSettings() on first method call, preserving the existing iOS vs
fallback behavior for get/set/watchKeys/clearWatch.

Changelog:
[GENERAL] [FIXED] - Defer Platform lookup in Settings.js to fix circular dependency startup crash

Test Plan:
- yarn jest packages/react-native/Libraries/Settings/__tests__/Settings-test.js --maxWorkers=2
  RED: circular-dependency test failed with "TypeError: Cannot read properties of undefined (reading 'OS')" at Settings.js:21
  GREEN: all 4 tests pass (circular init, lazy Platform access, iOS delegation, fallback)
- yarn jest packages/react-native/Libraries/Settings packages/react-native/Libraries/Utilities --maxWorkers=2
  15 tests pass, no regressions

Co-Authored-By: Claude <noreply@anthropic.com>
@meta-cla

meta-cla Bot commented Aug 10, 2026

Copy link
Copy Markdown

Hi @SnowingFox!

Thank you for your pull request and welcome to our community.

Action Required

In order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you.

Process

In order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA.

Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with CLA signed. The tagging process may take up to 1 hour after signing. Please give it that time before contacting us about it.

If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks!

@meta-cla

meta-cla Bot commented Aug 10, 2026

Copy link
Copy Markdown

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks!

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Aug 10, 2026
@meta-cla

meta-cla Bot commented Aug 10, 2026

Copy link
Copy Markdown

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks!

@facebook-github-tools facebook-github-tools Bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label Aug 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TypeError: Cannot read property 'OS' of undefined in Libraries/Settings/Settings.js due to circular dependency on startup

1 participant