Skip to content

fix(android): don't crash in Fragment.onCreateView on stale-fragment race#11264

Open
NathanWalker wants to merge 1 commit into
mainfrom
fix/android-fragment-race-throw
Open

fix(android): don't crash in Fragment.onCreateView on stale-fragment race#11264
NathanWalker wants to merge 1 commit into
mainfrom
fix/android-fragment-race-throw

Conversation

@NathanWalker

Copy link
Copy Markdown
Contributor

onCreateView already returns null when its entry, resolvedPage, or frame is missing, but it first called Trace.error, which rethrows through the registered error handler across the JNI boundary and turns the recoverable case into a fatal "Calling js method onCreateView failed" crash.

These nulls happen when the FragmentManager drives a stale fragment to CREATE_VIEW after NativeScript has already torn down the corresponding backstack entry (process death / activity recreation after rotation or theme change, clearHistory, or rapid navigate+goBack). The fragment should just be discarded, not crash the app.

Downgrade the three guards to Trace.messageType.warn so the existing return-null recovery path is actually reached, consistent with the existing onDestroy handling of the same race.

Fixes production crashlytics reports:

Fatal Exception: com.tns.NativeScriptException: Calling js method onCreateView failed
Error: fragment0[0]<null>.onCreateView: entry has no resolvedPage
       at com.tns.Runtime.callJSMethodNative(Runtime.java)
       at com.tns.Runtime.dispatchCallJSMethodNative(Runtime.java:1441)
       at com.tns.Runtime.callJSMethodImpl(Runtime.java:1327)
       at com.tns.Runtime.callJSMethod(Runtime.java:1314)
       at com.tns.Runtime.callJSMethod(Runtime.java:1291)
       at com.tns.Runtime.callJSMethod(Runtime.java:1287)
       at com.tns.FragmentClass.onCreateView(FragmentClass.java:55)
       at androidx.fragment.app.Fragment.performCreateView(Fragment.java:3119)
       at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:577)
       at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:286)
       at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2214)
       at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:2109)
       at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:2052)
       at androidx.fragment.app.FragmentManager$5.run(FragmentManager.java:703)
       at android.os.Handler.handleCallback(Handler.java:883)
       at android.os.Handler.dispatchMessage(Handler.java:100)
       at android.os.Looper.loop(Looper.java:214)
       at android.app.ActivityThread.main(ActivityThread.java:7631)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)

…race

onCreateView already returns null when its entry, resolvedPage, or frame is
missing, but it first called Trace.error, which rethrows through the registered
error handler across the JNI boundary and turns the recoverable case into a
fatal "Calling js method onCreateView failed" crash.

These nulls happen when the FragmentManager drives a stale fragment to
CREATE_VIEW after NativeScript has already torn down the corresponding
backstack entry (process death / activity recreation after rotation or
theme change, clearHistory, or rapid navigate+goBack). The fragment should
just be discarded, not crash the app.

Downgrade the three guards to Trace.messageType.warn so the existing
return-null recovery path is actually reached, consistent with the existing
onDestroy handling of the same race.
@nx-cloud

nx-cloud Bot commented Jun 9, 2026

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit 26d34e1

Command Status Duration Result
nx test apps-automated -c=android ✅ Succeeded 3m 53s View ↗
nx run-many --target=test --configuration=ci --... ✅ Succeeded <1s View ↗

💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗


☁️ Nx Cloud last updated this comment at 2026-06-09 22:14:54 UTC

// Recoverable race: a stale fragment is being driven to onCreateView by the
// FragmentManager after its entry was cleared.
// Using Trace.error (routes to an error handler, which throws) would be fatal as the error handler rethrows across the JNI boundary.
if (Trace.isEnabled()) {

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.

@NathanWalker We can't ignore the possibility that it may also occur if something goes wrong.
If it occurs too frequently in your apps, it's a sign there's something we shall take care of.
I'd suggest we removed the isEnabled check and use messageType.error instead to let message be printed no matter what.

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.

2 participants