Skip to content

[Due for payment 2026-10-23] [$175] Android - Spend - Merchant filter modal only shows Merchant title and Apply button #104133

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.5.10-0
Reproducible in staging?: Yes
Reproducible in production?: No
If this was caught during regression testing, add the test name, ID and link from BrowserStack: #83733
Email or phone of affected tester (no customers): [email protected]
Issue reported by: Applause Internal Team
Bug source: Exploratory - Significant User Experience Deterioration
Device used: Samsung Galaxy S25 FE / Android 16
App Component: Search

Action Performed:

  1. Launch Expensify app.
  2. Go to Spend > Expenses.
  3. Tap Filters.
  4. Tap Merchant.
  5. Enter anything > Confirm > Apply filters.
  6. Open merchant quick filter.

Expected Result:

Merchant filter modal will be shown completely.

Actual Result:

Merchant filter modal only shows Merchant title and Apply button.

Workaround:

Unknown

Platforms:

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

Screenshots/Videos

Bug7287405_1792084395242.Screen_Recording_20261016_010847_Expensify.1.mp4

View all open jobs on GitHub

Applause Internal Information
Exported by: Julia Ponikarchuk
Bug ID: 7287405

Upwork Automation - Do Not Edit
Issue OwnerCurrent Issue Owner: @truph01

Activity

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

  3. melvin-bot commented on Oct 15, 2026

    @melvin-bot

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

  4. melvin-bot commented on Oct 15, 2026

    @melvin-bot

    @neil-marcellini @truph01 you have been assigned to this deploy blocker because you reviewed the offending PR: #83733

  5. melvin-bot commented on Oct 15, 2026

    @melvin-bot

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

  6. github-actions commented on Oct 15, 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.
  7. truph01 commented on Oct 15, 2026

    @truph01
    Contributor

    @MelvinBot Post proposal

  8. MelvinBot commented on Oct 15, 2026

    @MelvinBot
    Contributor

    Deploy Blocker Investigation

    Causing PR: [Payment due @truph01] fix: Add Contains / Equal to match type for the Merchant filter [80823] (high confidence). It merged on 2026-10-14 and is in the 9.5.10-0 checklist. It is a frontend bug.

    Root cause: The Merchant quick-filter chip now renders MerchantFilterPopup, which reuses TextInputFilterContent. That component was built for the full-height advanced-filters page. Its root uses flex1 and puts the input and match-type list inside a ScrollView. The chip popover is sized by its content, so on native the ScrollView gets 0 height. Only the "Merchant" label and the Apply button (outside the ScrollView) remain visible.

    Recommendation: fix forward. The PR changes 48 files, and later PRs in the same checklist build on it, so a revert would likely conflict. Either:

    • give TextInputFilterContent a popover mode with no root flex1, no ScrollView, and an inline button, or
    • build MerchantFilterPopup like TextFilterPopup, with NegatableFilter, TextInput, and MerchantMatchTypeSelector placed directly in BasePopup.

    If a fix isn't ready quickly, revert the PR and resolve the conflicts.

    Investigation details
    1. Before: The chip used TextFilterPopup, which puts a plain TextInput in BasePopup with no ScrollView or flex1. The popup grows to fit its content: TextFilterPopup.tsx#L46-L68.
    2. The PR re-routes the chip to MerchantFilterPopup: useSearchFiltersBar.tsx#L123-L133.
    3. The new popup wraps the page content (MerchantFilterContent → TextInputFilterContent): MerchantFilterPopup.tsx#L47-L64, MerchantFilterContent.tsx#L91-L103.
    4. That content assumes a parent with height: the root is flex1 (L88), the input and the renderBelowInput match-type list sit in a ScrollView (L89-L117), and the Apply button renders outside it (L118): TextInputFilterContent.tsx#L87-L119.
    5. The popover gives it no height. Its wrapper has only width and safe-area padding: FilterPopupButton.tsx#L159. BasePopup is also content-sized: BasePopup.tsx#L47-L58.
    6. Why only native: On web, ScrollView is a div that sizes to its content. The advanced-filters page works because it is a full-height screen. iOS native likely has the same bug.

    Other candidates ruled out: Only Make report, expense, and member values copyable touches the filter-popup area, and it changes only DisplayPopup.tsx and list items, not the Merchant chip path.

    Assignees: The PR author HiepPP and reviewers truph01 and neil-marcellini are already assigned, which matches this finding.

    I did not reproduce this on a device. This run only had a web tester, and the bug is native-only.


    view run

  9. MelvinBot commented on Oct 15, 2026

    @MelvinBot
    Contributor

    Proposal

    What is the root cause of that problem?

    fix: Add Contains / Equal to match type for the Merchant filter [80823] switched the Merchant chip from TextFilterPopup to the new MerchantFilterPopup. The new popup reuses MerchantFilterContent → TextInputFilterContent, which was built for the full-height advanced-filters page.

    TextInputFilterContent has a flex1 root. It puts the input and the match-type list inside a ScrollView, and it renders the Apply button outside that ScrollView. The chip popover has no height of its own because it sizes to its content. On native, a flex1 child of a content-sized parent gets 0 height, so the ScrollView collapses. Only the "Merchant" label and the Apply button stay visible. Web is not affected because a web ScrollView grows to fit its content.

    Code references

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

    Build MerchantFilterPopup the same way as TextFilterPopup, so it sizes to its content. Leave the advanced-filters page unchanged.

    1. In MerchantFilterPopup, keep local state for value, isNegated, and merchantOperator. Seed them from getFilterNegatableValue and values[MERCHANT_OPERATOR].
    2. Render BasePopup with its default action buttons, onApply, and shouldSubmitOnEnter. Remove shouldShowActionButtons={false}.
    3. Inside BasePopup, render NegatableFilter with a TextInput, the same as TextFilterPopup. Below it, render MerchantMatchTypeSelector only when the filter is not negated. The selector already reserves a minHeight for its rows.
    4. On apply, validate with useTextFilterValidation. Then build the form values the same way MerchantFilterContent.updateMerchantFilter does. Move that mapping into a small shared helper so both surfaces use it.
    5. Stop using MerchantFilterContent in the chip popup.

    What alternative solutions did you explore? (Optional)

    Add a popover mode to TextInputFilterContent. It would drop the root flex1 and the ScrollView and render the button inline. MerchantFilterContent would also drop the flex1 around the selector. This keeps one component but adds layout branches to a shared component that other text filters use.

    Reverting the PR is possible but risky. It changes 48 files, and later PRs in the same checklist build on it.

    I haven't tested this on a device because the bug only happens on native.


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


    view run

  10. 3 remaining items

  11. changed the title [-]Android - Spend - Merchant filter modal only shows Merchant title and Apply button[/-] [+][$175] Android - Spend - Merchant filter modal only shows Merchant title and Apply button[/+] on Oct 15, 2026
  12. melvin-bot commented on Oct 15, 2026

    @melvin-bot
  13. neil-marcellini commented on Oct 15, 2026

    @neil-marcellini
    Contributor

    Fix was CPed to staging and it's being retested as requested here.

  14. izarutskaya commented on Oct 16, 2026

    @izarutskaya

    Issue is still reproducible
    Build 9.5.12-0
    Samsung Galaxy A40/Android 11 and Android 13

    MicrosoftTeams-video.15.mp4
    Screen.Recording.20261016.111244.Expensify.mp4
  15. izarutskaya commented on Oct 16, 2026

    @izarutskaya

    It's passed with the build #104141 (comment)

    Xiaomi Redmi Note 10 / Android 12

    Screenrecorder-2026-10-16-11-46-05-390.mp4
    Screen_Recording_20261016_120237_Expensify.Adhoc.mp4
  16. cristipaval commented on Oct 16, 2026

    @cristipaval
    Contributor

    CP'd the fix into staging

  17. m-natarajan commented on Oct 16, 2026

    @m-natarajan

    Not repro on Samsung Galaxy A40/Android 11/App/Build 9.5.12-1

    MicrosoftTeams-video.16.mp4
  18. changed the title [-][$175] Android - Spend - Merchant filter modal only shows Merchant title and Apply button[/-] [+][Due for payment 2026-10-23] [$175] Android - Spend - Merchant filter modal only shows Merchant title and Apply button[/+] on Oct 16, 2026
  19. melvin-bot commented on Oct 16, 2026

    @melvin-bot

    @truph01

    The solution for this issue has been 🚀 deployed to production 🚀 in version 9.5.12-1 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-10-23. 🎊

    The following checklist (instructions) will need to be completed before the issue can be closed. Please copy/paste the Contributor+ 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]. If no checklist is needed for this issue, you can click: [no checklist button]

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.DailyKSv2Engineering

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions