Repository navigation
HybridApp Android crash: getActivePolicy() returns null in SlidingMenuController Trips handler #82550
Description
Activity
- addedInternalRequires API changes or must be handled by Expensify staffRequires API changes or must be handled by Expensify staffBugSomething is broken. Auto assigns a BugZero manager.Something is broken. Auto assigns a BugZero manager.
on Feb 16, 2026 Triggered auto assignment to @greg-schroeder (
Bug), see https://stackoverflow.com/c/expensify/questions/14418 for more details. Please add this bug to a GH project, as outlined in the SO.- addedExternalAdded to denote the issue can be worked on by a contributorAdded to denote the issue can be worked on by a contributorand removedInternalRequires API changes or must be handled by Expensify staffRequires API changes or must be handled by Expensify staff
on Feb 16, 2026 - addedHelp WantedApply this label when an issue is open to proposals by contributorsApply this label when an issue is open to proposals by contributors
on Feb 16, 2026 Triggered auto assignment to Contributor-plus team member for initial proposal review - @Ollyws (
External)Unable to auto-create job on Upwork. The BZ team member should create it manually for this issue.
- addedMelvin TriageAutomatic AI Analysis of an issueAutomatic AI Analysis of an issue
on Feb 18, 2026 Proposal
Please re-state the problem that we are trying to solve in this issue.
On HybridApp Android, a fatal
RuntimeExceptionoccurs when the user taps any row in the sliding menu (not just Trips). The crash is caused by calling.getID()on anullreturn value fromgetActivePolicy()inSlidingMenuController.js. ThegetActivePolicy()call is at the top of theonRowTappedCallbackshandler — before any page-specific branching — so it crashes regardless of which menu item is tapped whenevergetActivePolicy()returnsnull.What is the root cause of that problem?
In
_viewSetOnRowTappedCallback(Mobile-Expensify/app/Controllers/SlidingMenuController.js), the very first line of the callback unconditionally callsself.app.getActivePolicy().getID()with no null guard:var onRowTappedCallbacks = function (rowIndex) { var row = self._navigationList[rowIndex]; var pageName = row.id; var activePolicyID = self.app.getActivePolicy().getID(); // crashes here ...
getActivePolicy()(Mobile-Expensify/app/expensify.js:6076) explicitly returnsnullwhen no valid policy is found and also triggersthis.signOut()as a side effect. When the user taps a menu item while no valid policy exists (e.g., during app restore, before policies fully load, or during sign-out),.getID()is called onnulland the app crashes.There is a secondary unguarded call site:
isTravelEnabled()(Mobile-Expensify/app/expensify.js:7706) also callsgetActivePolicy()and immediately accessesactivePolicy.getTravelSettings()andactivePolicy.isPolicyProvisioned()without null checks, which would crash ifgetActivePolicy()returns null there.Note: The issue description frames this as a race condition between two sequential
getActivePolicy()calls. While there technically are two calls (one at the top of the handler, one insideisTravelEnabled()), the primary crash happens at the very first call — before any TRIPS-specific code runs. It's a missing null guard, not a race between the two calls.What changes do you think we should make in order to solve the problem?
Two changes in
Mobile-Expensify:- In
SlidingMenuController.js— Move theactivePolicyIDassignment inside the TRIPS branch (since only the TRIPS path uses it), and add a null guard following the established codebase pattern:
if (pageName === SlidingMenuController.PAGES.TRIPS) { var activePolicy = self.app.getActivePolicy(); if (!_.isPolicy(activePolicy)) { return; } var activePolicyID = activePolicy.getID(); if (self.app.isTravelEnabled()) { // ... existing Travel_GenerateSpotnanaToken logic using activePolicyID } // ... existing fallback navigateToNewDot logic using activePolicyID return; }
- In
expensify.js— Add a null guard inisTravelEnabled()to returnfalseifgetActivePolicy()returns null:
var activePolicy = this.getActivePolicy(); if (!activePolicy) { return false; }
Both changes follow the established pattern used in
SettingsController.updateListItems(),CreateExpenseMenuController, andDropDownMenuControllerwhere the result ofgetActivePolicy()is stored in a variable and checked with_.isPolicy()before use.What alternative solutions did you explore? (Optional)
An alternative would be to make
getActivePolicy()itself never return null (e.g., return a default/empty policy object). However, this would mask a legitimate error state and the existingsignOut()side effect is intentional. The null guard approach is consistent with how this has been fixed elsewhere in the codebase (PR #13663 for #69370).
Next Steps for Contributor+ team: Reply with
@MelvinBot implement thisto create a draft PR, or@MelvinBot <your feedback>to refine this analysis.- In
I can't seem to reproduce this by navigating the the trips page.
It might not be easily reproducible, is it happening for more users?
115 remaining items
@QichenZhu Whoops! This issue is 2 days overdue. Let's get this updated quick!
@QichenZhu Uh oh! This issue is overdue by 2 days. Don't forget to update your issues!
I think we can close this.
Sounds like we are done
Reacted by Qichen Zhu- removed a parent issue
on Sep 23, 2026
Metadata
Metadata
Labels
Type
Projects
- StatusShow more project fieldsSUBISSUE

Crash Description
https://console.firebase.google.com/u/0/project/expensify-mobile-app/crashlytics/app/android:org.me.mobiexpensifyg/issues/af3985b17bad9e9e418b98b7168b33f1?time=7d&types=crash&versions=9.3.19-4%20(509031904);9.3.19-3%20(509031903);9.3.19-0%20(509031900)&sessionEventKey=699301EE027500015D088E24447AF092_2185872096679185833
On HybridApp Android, a fatal
RuntimeExceptionoccurs inSlidingMenuController.jswhen the user navigates to the Trips page. The crash is caused by calling.getID()on anullreturn value fromgetActivePolicy().Crash location:
Mobile-Expensify/app/Controllers/SlidingMenuController.jsline 397:Root Cause Analysis
This is inside the
TRIPSpage handler, which first checksself.app.isTravelEnabled()(line 395). If that returnstrue, it proceeds to callself.app.getActivePolicy().getID()— butgetActivePolicy()can returnnull.Why it returns null: In
Mobile-Expensify/app/expensify.js(line 6077),getActivePolicy()returnsnullwhen no valid policy is found, and also triggers a sign-out:The race condition:
isTravelEnabled()callsgetActivePolicy()internally (line 7707) and succeeds. But by the time the code callsgetActivePolicy()again on line 397, the policy may have been invalidated (e.g., sign-out started, or policy data cleared), causingnullto be returned and.getID()to crash with aTypeError: Cannot read properties of null.Proposed Fix
Add a null guard before calling
.getID(), or cache theactivePolicyresult from theisTravelEnabled()check:This avoids the double call to
getActivePolicy()and eliminates the window for the race condition.Related Issues
getActivePolicy()null pattern but forhasNonCashCardsin SettingsController (closed)Issue Owner
Current Issue Owner: @QichenZhu