You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Due for payment 2026-03-19] Report - Cancel payment doesn't work and leads to blank page #85019
Version Number: 9.3.36-0 Reproducible in staging?: Yes Reproducible in production?: No If this was caught during regression testing, add the test name, ID and link from BrowserStack:https://test-management.browserstack.com/projects/2219752/folder/13176792/test-cases/41237180 Email or phone of affected tester (no customers):gatantm+6210@gmail.com Issue reported by: Applause Internal Team Bug source: Regression TC Execution Device used: MacOS 26.2, Safari App Component: Chat Report View
Action Performed:
Launch expensify and go to WS tab
Open any WS chat and submit an expense to it
Approve and Pay the expense
Open the report select More > Cancel payment
Expected Result:
The payment is canceled and user sees it on the report
Actual Result:
The app is stuck on empty page. The payment is not canceled
👋 Friendly reminder that deploy blockers are time-sensitive ⏱ issues! Check out the open `StagingDeployCash` deploy checklist to see the list of PRs included in this release, then work quickly to do one of the following:
Identify the pull request that introduced this issue and revert it.
🔍 Investigation: Which PR caused Cancel Payment → blank page?
Summary: After investigating all 80+ PRs in the 9.3.36-0 staging release against the cancel payment flow, the most likely culprit is PR #84860 (Bump Onyx to 3.0.45), which introduced a new OnyxSnapshotCache caching layer that can serve stale data during batch Onyx updates — exactly the kind of update that cancelPayment triggers.
Symptoms
User opens workspace chat → submits expense → approves & pays → selects More > Cancel payment
App gets stuck on blank/empty page
Payment is NOT canceled (action didn't complete)
Reproducible in staging (9.3.36-0), NOT in production
This PR bumped react-native-onyx from 3.0.43 → 3.0.45, introducing a new OnyxSnapshotCache class that sits between useOnyx's useSyncExternalStoregetSnapshot() and the actual Onyx data store.
MoneyReportHeader subscribes to ~20 Onyx keys via useOnyx (src/components/MoneyReportHeader.tsx:226-290), all of which now use the new OnyxSnapshotCache. A single cancelPayment triggers a cascade of subscriber callbacks across all these hooks.
The new cache has asymmetric invalidation (OnyxSnapshotCache.invalidateForKey): member keys invalidate upward to collection keys, but collection keys do NOT cascade downward to members. If subscriber callbacks fire sequentially during the batch update, getSnapshot() for subscriptions that haven't received their callback yet will return stale cached results from OnyxSnapshotCache.
Potential for undefined/inconsistent state: If the cache is invalidated but the new value hasn't been written to OnyxCache yet, getSnapshot() could return undefined, causing MoneyReportHeader and ReportScreen to render with missing data — explaining the blank page.
Selector equality semantics changed: For hooks with selectors, values are now compared by reference (===) instead of the previous comparison method. This could cause certain selectors in MoneyReportHeader to miss updates they previously would have caught.
PRs Ruled Out
I investigated the following PRs and confirmed they do NOT modify the cancel payment flow:
Only MoneyReportView/MoneyRequestReportTransactionList display
Additional Context
The cancel payment flow in MoneyReportHeader.tsx:1496-1509 uses showConfirmModal from the useConfirmModal hook. On web, this modal uses shouldHandleNavigationBack: true, which pushes a browser history state and pops it with window.history.back() on close. On Safari specifically, this history manipulation could interact poorly with the Onyx cache changes, potentially navigating the user away before the confirmation completes — explaining both the blank page AND the payment not being canceled.
Recommended Next Steps
Quick validation: Try reverting react-native-onyx from 3.0.45 back to 3.0.43 and test cancel payment on Safari to confirm/deny this hypothesis.
Check the Onyx changelog between 3.0.43 and 3.0.45 for specific cache-related changes.
If confirmed, the Onyx team should review OnyxSnapshotCache.invalidateForKey() to ensure batch Onyx.merge operations invalidate all relevant cache entries atomically before any getSnapshot() calls.
Confidence: Medium — Code evidence strongly supports this hypothesis, but runtime logs or a revert test are needed for definitive confirmation.
changed the title [-]Report - Cancel payment doesn't work and leads to blank page[/-][+][Due for payment 2026-03-19] Report - Cancel payment doesn't work and leads to blank page[/+]on Mar 12, 2026
The solution for this issue has been 🚀 deployed to production 🚀 in version 9.3.36-10 and is now subject to a 7-day regression period 📆. Here is the list of pull requests that resolve this issue:
@iwiznia The PR fixing this issue has been merged! The following checklist (instructions) will need to be completed before the issue can be closed. Please copy/paste the BugZero Checklist from here into a new comment on this GH and complete it. If you have the K2 extension, you can simply click: [this button]
Activity
github-actions commentedon Mar 12, 2026
👋 Friendly reminder that deploy blockers are time-sensitive ⏱ issues! Check out the open `StagingDeployCash` deploy checklist to see the list of PRs included in this release, then work quickly to do one of the following:
melvin-bot commentedon Mar 12, 2026
Triggered auto assignment to @iwiznia (
DeployBlockerCash), see https://stackoverflowteams.com/c/expensify/questions/9980/ for more details.melvin-bot commentedon Mar 12, 2026
💬 A slack conversation has been started in #expensify-open-source
iwiznia commentedon Mar 12, 2026
@MelvinBot can you investigate which PR we deployed to staging recently caused this?
MelvinBot commentedon Mar 12, 2026
🔍 Investigation: Which PR caused Cancel Payment → blank page?
Summary: After investigating all 80+ PRs in the 9.3.36-0 staging release against the cancel payment flow, the most likely culprit is PR #84860 (Bump Onyx to 3.0.45), which introduced a new
OnyxSnapshotCachecaching layer that can serve stale data during batch Onyx updates — exactly the kind of update thatcancelPaymenttriggers.Symptoms
Primary Suspect: PR #84860 — Bump Onyx to 3.0.45
This PR bumped
react-native-onyxfrom 3.0.43 → 3.0.45, introducing a newOnyxSnapshotCacheclass that sits betweenuseOnyx'suseSyncExternalStoregetSnapshot()and the actual Onyx data store.Why this is suspicious:
cancelPayment()triggers batch Onyx updates on 4+ keys simultaneously (src/libs/actions/IOU/index.ts:10996-11086):COLLECTION.REPORT_ACTIONS,COLLECTION.REPORT(chat report),COLLECTION.REPORT(expense report — changesstatusNum,stateNum,isCancelledIOU), andCOLLECTION.NEXT_STEP.MoneyReportHeadersubscribes to ~20 Onyx keys viauseOnyx(src/components/MoneyReportHeader.tsx:226-290), all of which now use the newOnyxSnapshotCache. A singlecancelPaymenttriggers a cascade of subscriber callbacks across all these hooks.The new cache has asymmetric invalidation (
OnyxSnapshotCache.invalidateForKey): member keys invalidate upward to collection keys, but collection keys do NOT cascade downward to members. If subscriber callbacks fire sequentially during the batch update,getSnapshot()for subscriptions that haven't received their callback yet will return stale cached results fromOnyxSnapshotCache.Potential for undefined/inconsistent state: If the cache is invalidated but the new value hasn't been written to OnyxCache yet,
getSnapshot()could returnundefined, causingMoneyReportHeaderandReportScreento render with missing data — explaining the blank page.Selector equality semantics changed: For hooks with selectors, values are now compared by reference (
===) instead of the previous comparison method. This could cause certain selectors inMoneyReportHeaderto miss updates they previously would have caught.PRs Ruled Out
I investigated the following PRs and confirmed they do NOT modify the cancel payment flow:
cancelPaymentuntouchedAdditional Context
The cancel payment flow in
MoneyReportHeader.tsx:1496-1509usesshowConfirmModalfrom theuseConfirmModalhook. On web, this modal usesshouldHandleNavigationBack: true, which pushes a browser history state and pops it withwindow.history.back()on close. On Safari specifically, this history manipulation could interact poorly with the Onyx cache changes, potentially navigating the user away before the confirmation completes — explaining both the blank page AND the payment not being canceled.Recommended Next Steps
react-native-onyxfrom 3.0.45 back to 3.0.43 and test cancel payment on Safari to confirm/deny this hypothesis.OnyxSnapshotCache.invalidateForKey()to ensure batchOnyx.mergeoperations invalidate all relevant cache entries atomically before anygetSnapshot()calls.Confidence: Medium — Code evidence strongly supports this hypothesis, but runtime logs or a revert test are needed for definitive confirmation.
7 remaining items
m-natarajan commentedon Mar 12, 2026
Not repro, Chrome / v9.3.36-6
Screen.Recording.2026-03-12.at.17.37.20.mp4
luacmartins commentedon Mar 12, 2026
Fixed. Closing.
[-]Report - Cancel payment doesn't work and leads to blank page[/-][+][Due for payment 2026-03-19] Report - Cancel payment doesn't work and leads to blank page[/+]melvin-bot commentedon Mar 12, 2026
Reviewinglabel has been removed, please complete the "BugZero Checklist".melvin-bot commentedon Mar 12, 2026
The solution for this issue has been 🚀 deployed to production 🚀 in version 9.3.36-10 and is now subject to a 7-day regression period 📆. Here is the list of pull requests that resolve this issue:
If no regressions arise, payment will be issued on 2026-03-19. 🎊
melvin-bot commentedon Mar 12, 2026
@iwiznia The PR fixing this issue has been merged! The following checklist (instructions) will need to be completed before the issue can be closed. Please copy/paste the BugZero Checklist from here into a new comment on this GH and complete it. If you have the K2 extension, you can simply click: [this button]
melvin-bot commentedon Mar 12, 2026
Triggered auto assignment to @mallenexpensify (
Awaiting Payment)