Skip to content

Spend- Click "Reconciliation - All Expenses" exported file not covered all expenses #102103

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.92-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: #101522
Email or phone of affected tester (no customers): applausetester+dk56@applause.expensifail.com
Issue reported by: Applause Internal Team
Bug source: Pull Request QA execution
Device used: Windows 11 Home/Chrome
App Component: Search

Action Performed:

Preconditions:

  • Import a transaction (csv) file to an account
  • Create a workspace, enable Company cards or the Expensify Card
  1. Open https://staging.new.expensify.com/
  2. Navigate to Spend > Expense
  3. Set the filter: Expense type: Card, Card: "card name", Display > Group by: Card
  4. Click to select the card row
  5. Click on "Export" button on bottom taskbar
  6. Select "Reconciliation - All Expenses"
  7. Open the downloaded file

Expected Result:

The resulting CSV covers every expense on the selected card — including expenses further down the list that were never scrolled into view — not only the rows that happened to be loaded on screen.

Actual Result:

The file only contains 1 expense.
Step 5 and Step 7 in PR is failed

Workaround:

Unknown

Platforms:

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

Screenshots/Videos

Bug7267516_1790184195946.bandicam_2026-09-24_00-06-41-974.mp4

View all open jobs on GitHub

Applause Internal Information
Exported by: Nathan Lemma
Bug ID: 7267516

Activity

  1. added
    DeployBlockerCashThis issue or pull request should block deployment
    BugSomething is broken. Auto assigns a BugZero manager.
    on Sep 23, 2026
  2. applause-bot commented on Sep 23, 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/2c0283f316a57f8e71f98addaf767e0aa52624e8278c24752c0150248b533122

  3. melvin-bot commented on Sep 23, 2026

    @melvin-bot

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

  4. melvin-bot commented on Sep 23, 2026

    @melvin-bot

    @NikkiWines @ZhenjaHorbach you have been assigned to this deploy blocker because you reviewed the offending PR: #101522

  5. github-actions commented on Sep 23, 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.
  6. melvin-bot commented on Sep 23, 2026

    @melvin-bot

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

  7. MelvinBot commented on Sep 23, 2026

    @MelvinBot
    Contributor

    🔍 Investigation Summary

    Classification: Frontend bug
    Causing PR: #101522 - "Extend Reconciliation - All Expenses export to any group-by:card selection" by @MelvinBot (High confidence that this PR exposed the broken flow; Medium-High confidence on the exact mechanism below, since the server side of the export can't be inspected from this repo)
    Related Issues: [CFI] Add "Reconciliation - All Expenses" export option for NewDot (Workspace/Card admins + Card Statements search) (the issue PR #101522 implements)

    Recommendation: REVERT

    The "Reconciliation - All Expenses" option on a card group selection only exists because of #101522, and that PR's own description states the positive branch was never verified in a browser (the CI account has no imported card transactions), so the very step QA failed is the step that was never exercised. Reverting restores production behaviour (no templates offered for a group selection) and touches only one source file plus its test file.

    Assigned: @NikkiWines and @ZhenjaHorbach (approving reviewers of #101522) — already assigned by melvin-bot; the PR author is a bot, so no author assignment.
    Labels: No changes. DeployBlockerCash stays (App-side PR caused it, and the bug is not reproducible on production). DeployBlocker was never applied and is not being added.

    📋 Detailed Analysis

    Evidence

    • The reported flow is brand new: before #101522, every export template was hidden as soon as a group row was ticked, so "Export → Reconciliation - All Expenses" on a card group row could not be reached at all. That PR added the carve-out at useSearchBulkActions.ts#L1984-L1987 and the gate change at #L2250. This matches "Reproducible in production?: N/A - new feature".
    • It is the only PR on the current Deploy Checklist: New Expensify 2026-09-23 that touches this code path (src/hooks/useSearchBulkActions.ts, merged 2026-09-22, right before the 9.4.92 staging build).
    • The PR body itself flags the gap: "The positive branch could not be exercised — the CI test account has no imported card transactions… Steps 2–7 below still need a manual run on an account with real card data." The failing QA steps are exactly steps 5 and 7.
    • The unit tests added by the PR only assert the arguments the App passes (reportIDList: [], transactionIDList: ['tx2'], jsonQuery contains cardID); nothing covers what the backend actually returns for that request, so they pass while the flow is broken.

    Verification

    • Affected file: src/hooks/useSearchBulkActions.ts — it builds both the export menu and the export request.
    • gh pr view 101522 --json files → src/hooks/useSearchBulkActions.ts, tests/unit/hooks/useSearchBulkActionsExportTest.ts. The PR modifies exactly the file that owns the broken behaviour.
    • gh api repos/Expensify/App/commits?path=src/hooks/useSearchBulkActions.ts confirms Extend Reconciliation - All Expenses export to any group-by:card selection #101522 is the most recent change to that file and the only staged change affecting group-scoped template exports.

    Root Cause

    When a card group row is ticked, the export scope is carried entirely by the query, not by IDs — useSearchBulkActions.ts#L982-L1000 sends reportIDList: [], transactionIDList: [] (only individually-ticked rows survive) and a jsonQuery built by addSelectedGroupsFilter.

    addSelectedGroupsFilter only swaps in a cardID: filter and rebuilds the query with buildSearchQueryString, which preserves the root keys — including groupBy and limit. So the request sent to ExportSearchWithTemplate is still a grouped query (type:expense groupBy:card cardID:<id>), and one selected card group resolves to one group row → the CSV contains a single line. That is precisely the reported symptom.

    Two things in the repo show why the other export path does not hit this:

    1. "Current view" tells the backend to expand the groups. exportSearchItemsToCSV sends isGroupExport (ExportSearchItemsToCSVParams.ts#L11), the flag added in [Payment due @thelullabyy] Fix mixed group export selection together with paired Auth/Web changes, so the backend expands a grouped query into its individual expenses and merges them with transactionIDList. ExportSearchWithTemplateParams has no such parameter, so the template export has no way to say "expand these groups". Every other caller of queueExportSearchWithTemplate (e.g. useExportActions.ts#L156-L167) sends jsonQuery: '{}' plus explicit IDs, so Extend Reconciliation - All Expenses export to any group-by:card selection #101522 is the first code to send a grouped query to that command on a reachable path.
    2. Everywhere else the App wants a group's transactions, it drops groupBy and limit. See buildSpecificGroupQuery and buildDateRangeGroupQuery, both with explicit comments that limit bounds the group count and must go when groupBy goes. addSelectedGroupsFilter keeps both.

    Secondary defect on the same path (worth fixing whenever this is re-attempted): the template export serializes the query without searchKey (#L987-L993), while the CSV path deliberately includes it and warns that omitting it makes the exported set differ from the viewed set (#L1074-L1078) — which matters here because reconciliation searches are exactly the example named in that comment.

    Roll-forward shape, if a revert is not wanted: build the template's jsonQuery from a flattened group query (groupBy: undefined, limit: undefined, same cardID: filter, plus searchKey) the way buildSpecificGroupQuery does, so the scope no longer depends on a group-expansion flag the command does not have. That still needs a manual run against an account with imported card transactions, which is why a revert is the safer call inside the deploy window.

  8. IuliiaHerets commented on Sep 24, 2026

    @IuliiaHerets

    Chrome / v9.4.92-7, still repro

    bandicam.2026-09-24.12-07-42-421.mp4
  9. IuliiaHerets commented on Sep 24, 2026

    @IuliiaHerets

    But it is not repro on v9.4.92-8. The function is not there now

    bandicam.2026-09-24.16-44-20-645.mp4
  10. self-assigned this
    on Sep 24, 2026
  11. lakchote commented on Sep 24, 2026

    @lakchote
    Contributor

    But it is not repro on v9.4.92-8. The function is not there now

    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.EngineeringHourlyKSv2ReviewingHas a PR in review

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions