Repository navigation
fix: Invoice - stop infinite loading when viewing an offline-created invoice online - #97112
Conversation
…sify#96925) Offline-created invoices never wrote RAM_ONLY_REPORT_LOADING_STATE, so on reconnect the invoice report and its optimistic invoice room stayed pinned at isLoadingInitialReportActions and showed an infinite loading skeleton. Mirror the expense flow in MoneyRequestBuilder by stamping hasOnceLoadedReportActions: true for both reports in optimisticData. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Codecov Report❌ Looks like you've decreased code coverage for some files. Please write tests to increase, or at least maintain, the existing level of code coverage. See our documentation here for how to interpret this table.
|
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a200158223
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
…estarts The creation-time hasOnceLoadedReportActions stamp lives in a RAM-only key, so an app restart between the offline create and reconnect drops it, and the queued SendInvoice failure would leave the invoice room pinned on the loading skeleton again. When ReportFetchHandler intentionally skips openReport for an optimistic chat report, settle the loading state from the persisted optimistic data instead of relying solely on the RAM-only stamp. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
@dilshodmackbook-sketch please add screenshots/videos for all platforms |
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppandroid.movAndroid: mWeb Chromeandroid-mweb.moviOS: HybridAppios.moviOS: mWeb Safariios-mweb.movMacOS: Chrome / Safariweb.mov |
|
@dilshodmackbook-sketch Please follow the test steps and record a video instead of taking screenshots. |
|
@daledah Got it. I'm recording videos that follow the exact test steps for all platforms (web, iOS, and Android) and will attach them here shortly. |
|
@dilshodmackbook-sketch - please simplify all comments - we don't need to reference the linked GH issue in the code comments 🙏 thanks! |
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
@Beamanator Done |
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
|
🚧 Beamanator has triggered a test Expensify/App build. You can view the workflow run here. |
|
🧪🧪 Use the links below to test this adhoc build on Android, iOS, and Web. Happy testing! 🧪🧪
|
|
🚀 Deployed to staging by https://github.com/Beamanator in version: 9.4.46-0 🚀
|
Help site review — no changes requiredI reviewed the changes in this PR against the help site articles under Why: This is an internal bug fix, not a behavior or feature change a customer would need documented.
The existing invoicing help content already describes creating and viewing invoices correctly and remains accurate. @dilshodmackbook-sketch, please review the linked help site PR and confirm it reflects the current behavior. Then mark the linked help site PR (Note: since no documentation changes were required, no help site PR was created — there is nothing to review or mark ready. If you believe a specific article should be updated, let me know which one and what behavior to capture.) |
|
🚀 Deployed to production by https://github.com/marcaaron in version: 9.4.46-10 🚀
Bundle Size Analysis (Sentry): |
Explanation of Change
When an invoice is created offline,
buildOnyxDataForInvoice(SendInvoice.ts) writes the invoice report and the new invoice room as optimistic reports (isOptimisticReport: true) but — unlike every other money-request creation flow — it never stampsRAM_ONLY_REPORT_LOADING_STATE.hasOnceLoadedReportActions: true.The invoice room is a
CHAT(chatTypeINVOICE), andReportFetchHandlerdeliberately never callsopenReportfor an optimistic chat report, so nothing ever writes that flag. Worse, the fetch handler keeps re-armingisLoadingInitialReportActionsback totruewhilehasOnceLoadedReportActionsisfalse. So once the user reconnects and opens the invoice, the report is pinned in a loading state and shows an infinite skeleton. Because the create was rejected server-side (invalid company website), the report exists only in local Onyx, which is why clearing the cache makes it disappear.This brings
buildOnyxDataForInvoiceto parity with the expense flow inMoneyRequestBuilder: stamphasOnceLoadedReportActions: trueinoptimisticDatafor both the invoice report and the newly-created invoice room. The optimistic data is already the complete local truth for these reports, so "loaded" is correct from creation. Once the wait ends, the invoice room renders its locally-written created action, whose existingOfflineWithFeedbacksurfaces theerrorFields.createChatred-brick-road error thatfailureDataalready writes.isOptimisticReportandfailureDataare intentionally left untouched soclearCreateChatError's dismiss-and-delete behavior is preserved.Fixed Issues
$ #96925
PROPOSAL: #96925 (comment)
Tests
www.none.com).Offline tests
Same as the Tests steps above — the repro requires creating the invoice while offline, then going online.
QA Steps
www.none.com).PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectionAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native
Screen.Recording.2026-07-29.at.13.35.12.mp4
Android: mWeb Chrome
Screen.Recording.2026-07-29.at.12.02.26.mov
iOS: Native
Screen.Recording.2026-07-29.at.13.05.05.mp4
iOS: mWeb Safari
Screen.Recording.2026-07-29.at.12.26.29.mov
MacOS: Chrome / Safari
96925-fix.mp4