Sentry
Both groups share the same throw site and the same platform. Sentry split them, but they are one bug.
Impact (snapshot at filing)
- Users (last 7d): 11 across both groups
- Users (total since first seen): 11
- Events: 11
- First seen: 2026-08-02
- Last seen: 2026-08-08
- Platform: iOS (HybridApp, OldDot)
- App version(s): 9.4.47-7 and later
- Mechanism: nsexception (fatal, uncaught)
- Culprit:
-[YAPL logException:]
Stack trace (top frames, first-party only)
@app/managers/GuidedReviewManager.js:1749:44
this._getJobFromExpense(expense).isApproved
@app/Controllers/GuidedReviewReportController.js:257:63
@app/Controllers/ReportController.js:972:63
@app/Controllers/ReportController.js:1129:63
@app/Controllers/ReportController.js:1122:19
@app/Controllers/ReportController.js:678:25
@app/Controllers/ReportController.js:225:32
publish@app/libs/pubSub.js:38:15
@app/libs/reportUtils.js:209:27
Native frames show the throw happening during ListViewController.removeRowAnimated, so the report list is mutating while the guided review state updates.
Suspected cause
_getJobFromExpense(expense) returns undefined and the caller reads .isApproved off it without a guard. The surrounding native frames point at a row being removed from the list at the same time, so the likely trigger is a guided review job that has already been consumed or removed when the pubSub update arrives for its expense.
The fix is to null-check the result of _getJobFromExpense at line 1749 and bail out when the job is gone.
Reproduction
Unknown. Sentry events all involve a report list update that removes a row while a guided review session is open.
Related
Other unhandled crashes in the same file, listed for context. They are separate throw sites and are not fixed by this issue:
| Sentry ID |
Users (last 7d) |
Signature |
| APP-JRG (this issue) |
8 |
_getJobFromExpense(expense).isApproved at line 1749 |
| APP-JTG (this issue) |
3 |
same throw site, separate Sentry group |
| APP-JVS |
1 |
Error: Unable to find job for index 0 at line 586 |
| APP-JW7 |
2 |
report.getID undefined at line 933 — already tracked in Expensify/Expensify#125773, labelled Not a priority |
Upwork Automation - Do Not Edit
Sentry
Both groups share the same throw site and the same platform. Sentry split them, but they are one bug.
Impact (snapshot at filing)
-[YAPL logException:]Stack trace (top frames, first-party only)
Native frames show the throw happening during
ListViewController.removeRowAnimated, so the report list is mutating while the guided review state updates.Suspected cause
_getJobFromExpense(expense)returns undefined and the caller reads.isApprovedoff it without a guard. The surrounding native frames point at a row being removed from the list at the same time, so the likely trigger is a guided review job that has already been consumed or removed when the pubSub update arrives for its expense.The fix is to null-check the result of
_getJobFromExpenseat line 1749 and bail out when the job is gone.Reproduction
Unknown. Sentry events all involve a report list update that removes a row while a guided review session is open.
Related
Other unhandled crashes in the same file, listed for context. They are separate throw sites and are not fixed by this issue:
_getJobFromExpense(expense).isApprovedat line 1749Error: Unable to find job for index 0at line 586report.getIDundefined at line 933 — already tracked in Expensify/Expensify#125773, labelledNot a priorityUpwork Automation - Do Not Edit