Skip to content

Inconsistency when moving all unreported expenses offline during first & second bulk select #102310

Closed

Description

@applause-bot

If you haven’t already, check out our contributing guidelines for onboarding. To join our Slack channel, fill out this form.


Version Number: 9.4.94-0
Reproducible in staging?: Yes
Reproducible in production?: N/A - new feature, doesn't exist in prod
If this was caught during regression testing, add the test name, ID and link from BrowserStack: #98411
Email or phone of affected tester (no customers): jsdoijnodsdisojo@gmail.com
Issue reported by: Applause Internal Team
Bug source: Exploratory - Significant User Experience Deterioration
Device used: Mac 26.5 / Chrome
App Component: Search

Action Performed:

Precondition:

  • Create more than 50 unreported expenses.
  1. Go to staging.new.expensify.com
  2. Go to Account > Troubleshoot > Clear cache and restart > Reset and refresh.
  3. Go to Spend > Expenses.
  4. Bulk select all unreported expenses > Select all.
  5. Scroll down to load all expenses.
  6. Go offline.
  7. Click Move to report.
    → "You appear to be offline" modal is shown.
  8. Deselect all unreported expenses.
  9. Select all unreported expenses.
  10. Click Move to report.
    → Report RHP opens.

Expected Result:

In Step 7, user should be able to move all unreported expenses to report in offline mode because all expenses are loaded.

Actual Result:

In Step 7, You appear to be offline" modal is shown when moving all unreported expenses to report in offline mode.
In Step 10, after deselecting and reselecting all unreported expenses, Report RHP opens.

Workaround:

Unknown

Platforms:

  • Android: App
  • Android: mWeb Chrome
  • iOS: App
  • iOS: mWeb Safari
  • iOS: mWeb Chrome
  • Windows: Chrome
  • MacOS: Chrome Safari

Screenshots/Videos

Bug7269360_1790345458254.2.mp4

View all open jobs on GitHub

Applause Internal Information
Exported by: Svetlana Lazutkina
Bug ID: 7269360

Activity

  1. applause-bot commented on Sep 25, 2026

    @applause-bot
    Author

    While Applause doesn't embed attachments for this bug, here are the links for quick view:
    https://platform.applause.com/services/links/v1/external/c6f64d3bf425215864d106578a6745a099a5ac2e088a47d4098d9d3334449fd7

  2. added
    DeployBlockerCashThis issue or pull request should block deployment
    BugSomething is broken. Auto assigns a BugZero manager.
    on Sep 25, 2026
  3. melvin-bot commented on Sep 25, 2026

    @melvin-bot

    You have been assigned to this deploy blocker because you recently merged this PR: #98411

  4. github-actions commented on Sep 25, 2026

    @github-actions
    Contributor

    👋 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:

    1. Identify the pull request that introduced this issue and revert it.
    2. Find someone who can quickly fix the issue.
    3. Fix the issue yourself.
  5. melvin-bot commented on Sep 25, 2026

    @melvin-bot

    @mjasikowski @suneox you have been assigned to this deploy blocker because you reviewed the offending PR: #98411

  6. melvin-bot commented on Sep 25, 2026

    @melvin-bot

    💬 A slack conversation has been started in #expensify-open-source

  7. MelvinBot commented on Sep 25, 2026

    @MelvinBot
    Contributor

    Deploy Blocker Analysis

    Causing PR: Support 'Select all matching' when moving expenses to a report. It is in Deploy Checklist: New Expensify 2026-09-25. The bug is frontend only, and I'm highly confident in this cause.

    Recommendation: Fix forward. The bug only happens offline, in a new feature. It blocks the move instead of losing data, and deselecting then reselecting works around it. A revert would remove the whole feature.

    Proposal

    What is the root cause of that problem?

    "Select all" sets areAllMatchingItemsSelected = true. When you scroll and every page loads, that flag stays true. The reconcile effect leaves out totalSelectableItemsCount on purpose, and the flag is only recomputed when that count is passed.

    The new offline guard checks only the flag. It does not check whether any matching expenses are still unloaded. So the first attempt shows the offline modal even though everything is loaded.

    Deselect all calls toggleAll with the count, which clears the flag. On reselect, hasMoreResults is false, so the "Select all matching" option isn't shown. That makes it a plain select-all, so the guard doesn't fire and the RHP opens.

    The RHP has the same flaw. If only the button is fixed, getAllMatchingQueryParams still returns the query while the flag is true. The shouldBlockOfflineAllMatchingMove check in the RHP would then block choosing a report.

    Code references

    What changes do you think we should make in order to solve the problem?

    Treat "all matching" as unresolved only while some pages are still unloaded. After the last page loads, the explicit selection is the full set, so the move can use the transaction list both offline and online.

    1. In the "Move expenses" guard in useSearchBulkActions.ts, block offline only when areAllMatchingItemsSelected and hasUnloadedMatchingExpenses are both true.
    2. Add a hasMoreResults argument to getAllMatchingQueryParams. Have it return empty params when hasMoreResults is false. Pass the value from all three callers: SearchTransactionsChangeReport, DynamicNewReportWorkspaceSelectionPage, and DynamicIOURequestStepUpgrade.
    3. Add a unit test for this case: all matching selected, hasMoreResults false, offline. "Move expenses" should open the RHP, and the params should not include jsonQuery.

    What alternative solutions did you explore? (Optional)

    Clear areAllMatchingItemsSelected in the selection provider after the last page loads with no exclusions. This is riskier because it also changes the footer's "All matching items selected" text and other bulk actions.


    Next Steps for Contributor+ team:
    To accept: @MelvinBot implement [this](https://github.com/Expensify/App/issues/102310) to create a draft PR.
    To refine: @MelvinBot <your feedback>
    To reject: Explain why you are rejecting Melvin's proposal.


    view run

  8. suneox commented on Sep 25, 2026

    @suneox
    Contributor

    I think this is expected behavior based on this confirmation. Since we don't have any documentation mentioning this, if we decide to handle it, it should be tracked in a separate issue to define the expected behavior, since selecting all while offline can include expenses that haven't loaded yet.

    cc: @mjasikowski

  9. mjasikowski commented on Sep 28, 2026

    @mjasikowski
    Contributor

    Working as expected, closing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

BugSomething is broken. Auto assigns a BugZero manager.EngineeringHourlyKSv2

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions