Skip to content

[Due for payment 2026-02-19] [$250] Expenses - Total spend footer appears on Reports > Expenses after saving search with custom columns #78149

Closed

Description

@lanitochka17

If you haven’t already, check out our contributing guidelines for onboarding and email contributors@expensify.com to request to join our Slack channel!


Version Number: 9.2.84-0
Reproducible in staging?: Yes
Reproducible in production?: Yes
If this was caught during regression testing, add the test name, ID and link from BrowserStack: #77673
Email or phone of affected tester (no customers): jsoidjsodijosj@gmail.com
Issue reported by: Applause Internal Team
Bug source: Pull Request QA execution
Device used: Mac 26.1 / Chrome
App Component: Search

Action Performed:

  1. Go to staging.new.expensify.com
  2. Go to workspace chat.
  3. Create an expense.
  4. Go to Reports > Expenses.
    → Total spend footer is not shown on Reports > Expenses - Expected.
  5. Click Columns.
  6. Select any column and click Save.
  7. Click Filters > Save search.
  8. Click Expenses on LHN.

Expected Result:

Total spend footer will not appear on Reports > Expenses after saving search with custom columns.

Actual Result:

Total spend footer appears on Reports > Expenses after saving search with custom columns.

Workaround:

Unknown

Platforms:

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

Screenshots/Videos

Bug7033761_1766155951526.32.mp4

View all open jobs on GitHub

Upwork Automation - Do Not Edit
Issue Owner

Current Issue Owner: @laurenreidexpensify

Activity

  1. added
    BugSomething is broken. Auto assigns a BugZero manager.
    on Dec 19, 2025
  2. melvin-bot commented on Dec 19, 2025

    @melvin-bot

    Triggered auto assignment to @laurenreidexpensify (Bug), see https://stackoverflow.com/c/expensify/questions/14418 for more details. Please add this bug to a GH project, as outlined in the SO.

  3. ShridharGoel commented on Dec 19, 2025

    @ShridharGoel
    Contributor

    Proposal

    Please re-state the problem that we are trying to solve in this issue.

    The Reports > Expenses view should always hide the total spend footer for the default expenses search

    What is the root cause of that problem?

    The footer was rendered whenever the search metadata included a result count, regardless of whether the view was the default expenses search. After saving a search with custom columns, the metadata is present, so the footer appears again instead of staying hidden.

    let searchResults;
    if (currentSearchResults?.data) {
    searchResults = currentSearchResults;
    } else if (isSorting) {
    searchResults = lastNonEmptySearchResults.current;
    }
    const metadata = searchResults?.search;
    const shouldShowFooter = !!metadata?.count || selectedTransactionsKeys.length > 0;
    and
    const shouldShowFooter = !!metadata?.count || Object.keys(selectedTransactions).length > 0;
    const isDataLoaded = isSearchDataLoaded(searchResults, queryJSON);
    const shouldShowLoadingState = !isOffline && (!isDataLoaded || !!currentSearchResults?.search?.isLoading);
    return (
    <ScreenWrapper
    testID="SearchPageNarrow"
    shouldEnableMaxHeight
    offlineIndicatorStyle={styles.mtAuto}
    bottomContent={!searchRouterListVisible && <NavigationTabBar selectedTab={NAVIGATION_TABS.SEARCH} />}
    headerGapStyles={styles.searchHeaderGap}
    shouldShowOfflineIndicator={!!searchResults}
    >
    <View style={[styles.flex1, styles.overflowHidden]}>
    {!isMobileSelectionModeEnabled ? (
    <View style={[StyleUtils.getSearchPageNarrowHeaderStyles(), searchRouterListVisible && styles.flex1, styles.mh100]}>
    <View style={[styles.zIndex10, styles.appBG]}>
    <TopBar
    shouldShowLoadingBar={shouldShowLoadingState}
    breadcrumbLabel={translate('common.reports')}
    shouldDisplaySearch={false}
    cancelSearch={shouldDisplayCancelSearch ? cancelSearchCallback : undefined}
    />
    </View>
    <View style={[styles.flex1]}>
    <Animated.View
    style={[
    topBarAnimatedStyle,
    !searchRouterListVisible && styles.narrowSearchRouterInactiveStyle,
    styles.flex1,
    styles.bgTransparent,
    styles.searchTopBarZIndexStyle,
    ]}
    >
    <View style={[styles.flex1, styles.pt2, styles.appBG]}>
    <SearchPageHeader
    queryJSON={queryJSON}
    searchRouterListVisible={searchRouterListVisible}
    hideSearchRouterList={() => {
    setSearchRouterListVisible(false);
    }}
    onSearchRouterFocus={() => {
    topBarOffset.set(StyleUtils.searchHeaderDefaultOffset);
    setSearchRouterListVisible(true);
    }}
    headerButtonsOptions={headerButtonsOptions}
    handleSearch={handleSearchAction}
    isMobileSelectionModeEnabled={isMobileSelectionModeEnabled}
    />
    </View>
    <View style={[styles.appBG]}>
    {!searchRouterListVisible && (
    <SearchFiltersBar
    queryJSON={queryJSON}
    headerButtonsOptions={headerButtonsOptions}
    isMobileSelectionModeEnabled={isMobileSelectionModeEnabled}
    />

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

    • Detect when the current query is the default expenses search and block the metadata-based footer from rendering.
    • Keep showing the footer when the user selects transactions, so bulk actions still have context.

    Updated code snippets:

    src/pages/Search/SearchPage.tsx

        const metadata = searchResults?.search;
        const isDefaultExpensesSearch = queryJSON ? isDefaultExpensesQuery(queryJSON) : false;
        const shouldShowFooter = (!!metadata?.count && !isDefaultExpensesSearch) || selectedTransactionsKeys.length > 0;

    src/pages/Search/SearchPageNarrow.tsx

        const isDefaultExpensesSearch = queryJSON ? isDefaultExpensesQuery(queryJSON) : false;
        const shouldShowFooter = (!!metadata?.count && !isDefaultExpensesSearch) || Object.keys(selectedTransactions).length > 0;
  4. bernhardoj commented on Dec 20, 2025

    @bernhardoj
    Contributor

    Proposal

    Please re-state the problem that we are trying to solve in this issue.

    The total footer is shown on the Expense tab after saving a type expense search with custom column and opening that saved search.

    What is the root cause of that problem?

    The total will be shown if the saved search matches the current similarSearchHash.

    for (const savedSearch of savedSearchValues) {
    const searchData = buildSearchQueryJSON(savedSearch.query);
    if (searchData && searchData.similarSearchHash === similarSearchHash) {
    return true;
    }
    }

    In our case, the similarSearchHash between the saved search and Expense tab is the same, even though the saved search has custom column. It's because similarSearchHash doesn't include the custom column and sorting query.

    const similarSearchHash = hashText(Array.from(filterSet).join(''), 2 ** 32);
    const recentSearchHash = hashText(orderedQuery, 2 ** 32);
    orderedQuery += ` ${CONST.SEARCH.SYNTAX_ROOT_KEYS.SORT_BY}:${query.sortBy}`;
    orderedQuery += ` ${CONST.SEARCH.SYNTAX_ROOT_KEYS.SORT_ORDER}:${query.sortOrder}`;
    orderedQuery += ` ${CONST.SEARCH.SYNTAX_ROOT_KEYS.COLUMNS}:${Array.isArray(query.columns) ? query.columns.join(',') : query.columns}`;

    I think the real problem here is that the save search is shown for type:expense with custom columns.

    The save search button is shown because isCannedSearchQuery checks for custom column, but we can see that it doesn't check for sorting query.

    function isCannedSearchQuery(queryJSON: SearchQueryJSON) {
    const selectedColumns = queryJSON.columns ?? [];
    const defaultColumns = Object.values(CONST.SEARCH.TYPE_DEFAULT_COLUMNS.EXPENSE_REPORT);
    const hasCustomColumns = !arraysEqual(defaultColumns, selectedColumns) && selectedColumns.length > 0;
    return !queryJSON.filters && !queryJSON.policyID && !queryJSON.status && !hasCustomColumns;
    }

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

    We should remove checking the custom column query from isCannedSearchQuery.

  5. melvin-bot commented on Dec 23, 2025

    @melvin-bot

    @laurenreidexpensify Whoops! This issue is 2 days overdue. Let's get this updated quick!

  6. melvin-bot commented on Dec 24, 2025

    @melvin-bot

    @laurenreidexpensify Huh... This is 4 days overdue. Who can take care of this?

  7. melvin-bot commented on Dec 27, 2025

    @melvin-bot

    @laurenreidexpensify 6 days overdue. This is scarier than being forced to listen to Vogon poetry!

  8. added
    ExternalAdded to denote the issue can be worked on by a contributor
    BZ Test Jan 26Lauren R running tests on removing BZ from certain parts in issue flows
    on Dec 29, 2025
  9. changed the title [-]Expenses - Total spend footer appears on Reports > Expenses after saving search with custom columns[/-] [+][$250] Expenses - Total spend footer appears on Reports > Expenses after saving search with custom columns[/+] on Dec 29, 2025
  10. melvin-bot commented on Dec 29, 2025

    @melvin-bot
  11. added
    Help WantedApply this label when an issue is open to proposals by contributors
    on Dec 29, 2025
  12. 34 remaining items

  13. melvin-bot commented on Feb 12, 2026

    @melvin-bot

    The solution for this issue has been 🚀 deployed to production 🚀 in version 9.3.17-9 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-02-19. 🎊

    For reference, here are some details about the assignees on this issue:

    • @ShridharGoel requires payment through NewDot Manual Requests
    • @brunovjk requires payment through NewDot Manual Requests
  14. melvin-bot commented on Feb 12, 2026

    @melvin-bot

    @ShridharGoel / @brunovjk @laurenreidexpensify 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]

  15. brunovjk commented on Feb 17, 2026

    @brunovjk
    Contributor

    BugZero Checklist:

    • [Contributor] The offending PR has been commented on, pointing out the bug it caused and why, so the author and reviewers can learn from the mistake.

      Link to comment:

    • [Contributor] If the regression was CRITICAL (e.g. interrupts a core flow) A discussion in #expensify-open-source has been started about whether any other steps should be taken (e.g. updating the PR review checklist) in order to catch this type of bug sooner.

      Link to discussion:

    • [Contributor] If it was decided to create a regression test for the bug, please propose the regression test steps using the template below to ensure the same bug will not reach production again.

    Regression Test Proposal

    Test:

    1. Go to workspace chat.
    2. Create an expense.
    3. Go to Reports Expenses.
    4. → Total spend footer is not shown on Reports Expenses - Expected.
    5. Click Columns.
    6. Select any column and click Save.
    7. Click Filters Save search.
    8. Click Expenses on LHN.
    9. Total spend footer should not appear on Reports Expenses.
    10. Ensure that the footer shows for all suggested searches and saved searches.
    11. Go to Reports Expenses
    12. Select a few expenses.
    13. Ensure that the footer shows when there are selections.
    14. Unselect all.
    15. Footer should not show after unselection.

    Do we agree 👍 or 👎

  16. melvin-bot commented on Feb 19, 2026

    @melvin-bot

    Payment Summary

    Upwork Job

    BugZero Checklist (@laurenreidexpensify)

    • (if NewFeature) I have created a PR for any necessary HelpDot updates, or I confirmed no updates are necessary.
    • I have verified the correct assignees and roles are listed above and updated the necessary manual offers
    • I have verified that there are no duplicate or incorrect contracts on Upwork for this job (https://www.upwork.com/ab/applicants/2005596160519129216/hired)
    • I have verified the PR was not reverted
    • I have applied any discounts due to bugs/regressions introduced by this PR
    • I have paid out the Upwork contracts or cancelled the ones that are incorrect
    • I have verified the payment summary above is correct
  17. ShridharGoel commented on Feb 19, 2026

    @ShridharGoel
    Contributor

    Not overdue, just due for payment

  18. laurenreidexpensify commented on Feb 20, 2026

    @laurenreidexpensify
    Contributor

    Payment Summary:

    • @ShridharGoel requires payment through NewDot Manual Requests $250
    • @brunovjk requires payment through NewDot Manual Requests $250
  19. JmillsExpensify commented on Feb 21, 2026

    @JmillsExpensify
    Contributor

    $250 approved for @ShridharGoel

  20. twisterdotcom commented on Feb 25, 2026

    @twisterdotcom
    Contributor

    @brunovjk has submitted payment for this report on ND here.

    SO: https://stackoverflowteams.com/c/expensify/questions/7582

    Zapier Logs Run ID: 00040eee-6724-a50a-5fd0-e0f3de552d24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Awaiting PaymentAuto-added when associated PR is deployed to productionBZ Test Jan 26Lauren R running tests on removing BZ from certain parts in issue flowsBugSomething is broken. Auto assigns a BugZero manager.DailyKSv2ExternalAdded to denote the issue can be worked on by a contributor

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions