Skip to content

[$175] Search - Error and From filter dropped after entering "group-by: reports" on a saved search (follow-up to #89168) #104287

Open

Description

@MelvinBot

Follow-up to [$250] Search - Error occurs after adding "group-by: reports" to the search query.

fix: prevent search error when using group-by reports fixed the originally reported case. During regression testing, QA could still reproduce the bug on staging v9.5.6-0 by following the regression test steps below. The contributor and C+ agreed this is a separate flow that should be handled in a new issue (discussion).

Version Number: v9.5.6-0
Reproducible in staging?: Yes
Reproducible in production?: Not checked
App Component: Search

Action Performed:

Precondition:

  • Log in with an account that has some expenses.

Steps:

  1. Go to Spend > Expenses.
  2. Open Advanced filters.
  3. Select From.
  4. Select the account you are currently logged in with.
  5. Apply the filter.
  6. Save the search.
  7. Click View results.
  8. In the Search bar, enter group-by: reports.
  9. Submit the search.

Expected Result:

No error occurs, and the existing From filter remains applied.

Actual Result:

The bug still reproduces in this flow (see video). In the original report, an error appeared and the From filter disappeared.

Platforms:

  • Windows: Chrome (others not checked)

Screenshots/Videos

Recording.3681.mp4
Issue OwnerCurrent Issue Owner: @nabi-ebrahimi
Upwork Automation - Do Not Edit

Activity

  1. added
    BugSomething is broken. Auto assigns a BugZero manager.
    on Oct 16, 2026
  2. trentpetty commented on Oct 16, 2026

    @trentpetty

    @MelvinBot Why was I assigned a bug issue?

  3. MelvinBot commented on Oct 16, 2026

    @MelvinBot
    ContributorAuthor

    I assigned you because mallenexpensify asked for it on the original issue, [Due for payment 2026-10-01] [$250] Search - Error occurs after adding "group-by: reports" to the search query.

    1. mallenexpensify asked jasperhuangg to have me create an issue and assign you and nabi-ebrahimi.
    2. jasperhuangg agreed and asked me to create it.
    3. I created this issue and assigned you, as mallenexpensify suggested.

    If you shouldn't be on this issue, ask mallenexpensify to reassign it.


    view run

  4. mallenexpensify commented on Oct 16, 2026

    @mallenexpensify
    Contributor

    @nabi-ebrahimi can you comment so we can assign you? Thx

  5. nabi-ebrahimi commented on Oct 17, 2026

    @nabi-ebrahimi
    Contributor

    7. @nabi-ebrahimi can you comment so we can assign you? Thx

    Hi @mallenexpensify, please assign me here. thanks.

  6. added
    ExternalAdded to denote the issue can be worked on by a contributor
    on Oct 17, 2026
  7. melvin-bot commented on Oct 17, 2026

    @melvin-bot

    Current assignee @truph01 is eligible for the External assigner, not assigning anyone new.

  8. changed the title [-]Search - Error and From filter dropped after entering "group-by: reports" on a saved search (follow-up to #89168)[/-] [+][$175] Search - Error and From filter dropped after entering "group-by: reports" on a saved search (follow-up to #89168)[/+] on Oct 17, 2026
  9. melvin-bot commented on Oct 17, 2026

    @melvin-bot
  10. removed
    ExternalAdded to denote the issue can be worked on by a contributor
    on Oct 17, 2026
  11. khizzcr7 commented on Oct 18, 2026

    @khizzcr7

    Proposal

    Root cause: reports is not a valid group-by value. CONST.SEARCH.GROUP_BY (src/CONST/index.ts) only defines from, card, withdrawal-id, category, merchant, tag, day, month, week, year, quarter - there is no reports, and the parser's GROUP_BY_DEFAULT_SORT map (src/libs/SearchParser/searchParser.peggy) has no entry for it either. However, the peggy defaultFilter rule accepts any identifier as the groupBy value: updateDefaultValues("groupBy", value) stores it unvalidated, and deriveGroupByDefaults silently no-ops for unknown values. So the invalid groupBy: "reports" survives parsing into the query JSON. The #89168 fix stopped the original hard error, but in this saved-search flow the invalid value still travels through the submit/rebuild pipeline (getQueryWithUpdatedValues -> buildSearchQueryString in src/libs/SearchQueryUtils.ts), where the error resurfaces and the existing from: filter is lost from the rebuilt query.

    Fix: Validate the groupBy value against CONST.SEARCH.GROUP_BY where user input enters the pipeline - in updateDefaultValues in searchParser.peggy (and/or getQueryWithUpdatedValues in src/libs/SearchQueryUtils.ts). When the value is not a recognized group-by, keep the query's previous groupBy (or omit the token) instead of carrying the invalid value forward. This keeps the existing From filter intact and avoids the error path entirely, matching the expected result.

    Verification:

    1. Follow the issue's repro steps on staging (saved expense search with a From filter, type group-by: reports, submit): confirm no error appears and the From filter chip remains applied with correct results.
    2. Add unit tests covering group-by: reports combined with a from: filter, asserting the from filter survives the parse -> rebuild round-trip and no error is thrown.
    3. Run the existing SearchQueryUtils and search parser test suites to check for regressions.
  12. jloa-dev commented on Oct 19, 2026

    @jloa-dev

    Contributor details
    Your Expensify account email: jloa.dev@gmail.com
    Upwork Profile Link: https://www.upwork.com/freelancers/~0163955a2ba22190aa

    Proposal

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

    When a saved search containing an existing From filter is viewed, and the user enters group-by: reports in the search bar and submits, an error occurs and the From filter is unexpectedly dropped.

    What is the root cause of that problem?

    In src/libs/SearchQueryUtils.ts (inside buildSearchQueryString and query normalization when handling groupBy modifiers):
    When group-by: reports is appended to an existing query string of a saved search, getSearchQueryJSON parses the query tokens. During the transition from the flat expense view to the report grouped view, the search query normalizer checks filter compatibility with groupBy.
    Specifically, the from filter parameter was using direct user account identification that the report-level group parser treats as non-groupable in saved queries if not explicitly retained in the sanitized query options (SearchQueryUtils.ts:sanitizeSearchValue). Because group-by: reports forces report-level aggregation, the query sanitizer strips filters not explicitly listed in the allowed grouped filter set, leading to the parameter being dropped and an undefined field error when fetching report-grouped results.

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

    1. In src/libs/SearchQueryUtils.ts, ensure that when parsing and sanitizing group-by: reports, user-specified filters such as from and to are preserved across both flat and grouped search views:
    function sanitizeFiltersForGroupBy(queryJSON: SearchQueryJSON): SearchQueryJSON {
        return {
            ...queryJSON,
            filters: {
                ...queryJSON.filters,
            },
        };
    }
    1. In src/libs/actions/Search.ts, ensure saved search re-execution retains all active filter criteria before appending the groupBy parameter to the search URL.

    What specific scenarios should we cover in automated tests?

    In tests/unit/SearchQueryUtilsTest.ts:

    • Add a test verifying that adding group-by: reports to a search query containing from:<accountID> preserves the from filter without dropping it.
    • Add a test verifying that no syntax or parser error is thrown on saved search report groupings.
  13. melvin-bot commented on Oct 19, 2026

    @melvin-bot

    ✅ Contributor details stored successfully. Thank you for contributing to Expensify!

  14. nabi-ebrahimi commented on Oct 19, 2026

    @nabi-ebrahimi
    Contributor

    Proposal

    I worked on the original issue, #89168, and its fix in #99503. This follow-up reproduces through a different input: the top-right Search button beside Concierge, opened while viewing a saved search.

    Root cause

    Two behaviors combine here:

    1. SearchRouter does not initialize its input from the saved search when searchContext.shouldShowSearchQuery is false. Submitting group-by: reports therefore starts from that text alone and loses the saved search’s from: filter before the API request.
    2. The defaultFilter rule in src/libs/SearchParser/searchParser.peggy accepts reports as a groupBy value, although it is not a supported grouping. The resulting query reaches Search and receives 401 Invalid Query.

    The original PR addressed the earlier Search input flow; it did not cover this saved-search router path.

    Proposed solution

    • In src/components/Search/SearchRouter/SearchRouter.tsx, initialize the top-right router from the current saved search even when shouldShowSearchQuery is false. Reuse buildUserReadableQueryString and buildSubstitutionsMap so the existing filters remain visible and their readable values map back to IDs on submission.
    • In src/libs/SearchParser/searchParser.peggy, reject an unsupported groupBy value in defaultFilter before it updates parser defaults. Regenerate searchParser.js from the grammar. This lets getQueryWithUpdatedValues rebuild a valid query while retaining the existing from: filter.

    This keeps the changes in the two paths responsible for the behavior, without adding search state or changing the API.

    Edge cases and verification

    1. Save an expense search with From = current user, view its results, open the top-right Search button beside Concierge, enter group-by: reports, and submit. The From filter should remain applied, results should load, and the invalid-search error should not appear.
    2. Repeat with a supported grouping such as group-by: merchant. It should still apply normally.
    3. Check a regular, unsaved search. Opening its router should retain its existing query-display behavior.
    4. Check a query with another valid grouping followed by group-by: reports. The unsupported value should not replace the valid grouping.
    5. Verify parser and query-rebuild tests cover unsupported grouping plus from:. Quoted "group-by: reports" should continue to behave as keyword text, since quotes change its meaning.
  15. truph01 commented on Oct 20, 2026

    @truph01
    Contributor

    @jasperhuangg Please assign @nabi-ebrahimi since they've worked on the previous issue #89168

  16. melvin-bot commented on Oct 20, 2026

    @melvin-bot

    @jasperhuangg — to hire @nabi-ebrahimi on Upwork, add the External label so a job is created and the offer is sent automatically.

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.ReviewingHas a PR in reviewWeeklyKSv2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions