Skip to content

[0.81] Prevent partially initialized TurboModules during shutdown - #16369

Merged
Vladimir Morozov (vmoroz) merged 2 commits into
0.81-stablefrom
user/khosany/fix-turbomodule-teardown-11996737
Sep 11, 2026
Merged

Vladimir Morozov (vmoroz) merged 2 commits into
0.81-stablefrom
user/khosany/fix-turbomodule-teardown-11996737

Conversation

@Khalef1

@Khalef1 Khalef Hosany (Khalef1) commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Description

Type of Change

  • Bug fix (non-breaking change which fixes an issue)

Why

Access violation in BlobTurboModule::CreateFromParts because m_resource is null. This regressed after #16237: during instance teardown, REACT_INIT is skipped when the runtime handle is null, but the lazy TurboModule can still be returned to JavaScript. The module is then callable without its initializer having populated its state. The same partial-initialization pattern can affect other lazy TurboModules.

What

  • Refuse lazy TurboModule creation after the React context or JSI runtime is unavailable.
  • Hold the acquired runtime handle throughout module registration so teardown cannot invalidate it between the availability check and initializer execution.
  • Release the temporary runtime handle after registration to avoid extending the runtime lifetime.
  • Add the react-native-windows patch change file.

Screenshots

Not applicable.

Testing

  • yarn format:verify
  • yarn beachball check --branch origin/0.81-stable

Changelog

Should this change be included in the release notes: yes

Prevent lazy TurboModules from being created without a runtime during shutdown.

Microsoft Reviewers: Open in CodeFlow

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: e5dad4bf-4f71-43ee-aa7f-d2f11d43121e
Copilot AI balanced review requested due to automatic review settings August 15, 2026 07:06
@Khalef1
Khalef Hosany (Khalef1) requested a review from a team as a code owner August 15, 2026 07:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Prevents lazy TurboModules from being returned with uninitialized runtime-dependent state during shutdown.

Changes:

  • Validates and retains the JSI runtime during module registration.
  • Releases the temporary runtime handle afterward.
  • Adds a patch change file.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
vnext/Microsoft.ReactNative/TurboModulesProvider.cpp Guards and stabilizes TurboModule initialization.
change/react-native-windows-c5366f79-8343-45d0-9916-3f13b872c4d8.json Records the patch release note.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread vnext/Microsoft.ReactNative/TurboModulesProvider.cpp
@vmoroz

Vladimir Morozov (vmoroz) commented Aug 18, 2026

Copy link
Copy Markdown
Member

Khalef Hosany (@Khalef1) , could you please check that holding the runtme handler inside of the Turbo Modules does not create the ref counting loops and thus the memory leaks?

Should we rather use a weak ref instead of the strong ref?

@JunielKatarn

Copy link
Copy Markdown
Contributor

Khalef Hosany (Khalef Hosany (@Khalef1)) , could you please check that holding the runtme handler inside of the Turbo Modules does not create the ref counting loops and thus the memory leaks?

Should we rather use a weak ref instead of the strong ref?

Vladimir Morozov (@vmoroz) as discussed offline, it appears the strong reference is only held from instantiation to initialization.
This was deemed as acceptable.

Can you approve if you see no further issues?

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Regression coverage and the required macOS companion validation are missing.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (1)

vnext/Microsoft.ReactNative/TurboModulesProvider.cpp:40

  • vnext/Microsoft.ReactNative.Cxx/README.md:18-31,57-63 explicitly lists this file and requires edits to be validated by a companion react-native-macos PR plus the RNTester Snapshot/Screenshot test. Neither that PR nor its validation result is linked here; please provide them before merging so this shared implementation is not broken on macOS.
  TurboModuleBuilder(const IReactContext &reactContext, IInspectable runtimeHandle) noexcept
      : m_reactContext(reactContext), m_runtimeHandle(std::move(runtimeHandle)) {}
  • Files reviewed: 2/2 changed files
  • Comments generated: 1
  • Review effort level: Balanced

Comment on lines +496 to +500
auto runtimeHandle = winrt::get_self<winrt::Microsoft::ReactNative::implementation::ReactContext>(m_reactContext)
->GetInner()
.JsiRuntime();
if (!runtimeHandle) {
return nullptr;
m_moduleBuilder(winrt::make_self<TurboModuleBuilder>(reactContext)),
m_providedModule(reactModuleProvider(m_moduleBuilder.as<IReactModuleBuilder>())) {
m_moduleBuilder(winrt::make_self<TurboModuleBuilder>(reactContext, std::move(runtimeHandle))) {
m_providedModule = reactModuleProvider(m_moduleBuilder.as<IReactModuleBuilder>());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this moved into the constructor body?

return nullptr;
}

auto runtimeHandle = winrt::get_self<winrt::Microsoft::ReactNative::implementation::ReactContext>(m_reactContext)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(nit) Keep the ABI-related comment?

@vmoroz
Vladimir Morozov (vmoroz) merged commit a88d2a3 into 0.81-stable Sep 11, 2026
37 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants