Skip to content

Android - Expense - List report field auto closes when there are at least 8 list values #101823

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.91-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: github.com//pull/100735
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: Samsung Galaxy S25 FE / Android 16
App Component: Money Requests

Action Performed:

Precondition:

  • Create list type report field with at least 8 list values.
  1. Launch Expensify app.
  2. Go to workspace chat.
  3. Create two expenses.
  4. Open the expense.
  5. Tap on the list report field.

Expected Result:

List report field will not close after opening it.

Actual Result:

List report field closes after opening it.
It requires a few attempts for it to not close after opening it.

Workaround:

Unknown

Platforms:

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

Screenshots/Videos

Bug7265717_1790022008859.Screen_Recording_20260922_041716_Expensify.mp4

View all open jobs on GitHub

Applause Internal Information
Exported by: Mita Rachim
Bug ID: 7265717

Activity

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

  3. melvin-bot commented on Sep 22, 2026

    @melvin-bot

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

  4. github-actions commented on Sep 22, 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 22, 2026

    @melvin-bot

    @Gonals @daledah you have been assigned to this deploy blocker because you reviewed the offending PR: #100735

  6. melvin-bot commented on Sep 22, 2026

    @melvin-bot

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

  7. MelvinBot commented on Sep 22, 2026

    @MelvinBot
    Contributor

    🔍 Investigation Summary

    Classification: Frontend bug
    Causing PR: Show up to three report fields per row and edit them inline (Expensify/App#100735) — authored by @MelvinBot, merged by @Gonals, approved by @Gonals and @daledah (High confidence)
    Related Issues: Android - Expense - List dopdown auto closes after focusing on text field and opening list (Expensify/App#101802), Android - Expense - Report auto scrolls to bottom after opening report field (Expensify/App#101799), Expense - Cursor appears briefly on list report field after clicking on it (Expensify/App#101804), Expense - No background blur when Month/Year RHP is opened while editing report field inline (Expensify/App#101810) — all from the same PR

    Recommendation: REVERT

    PR #100735 is the only reason a list report field opens a dropdown at all (it previously navigated to a full page), and it has produced five Android/inline-report-field deploy blockers in this one release; the remaining fix would have to change FilterPopupButton, which is shared by the Search and Table filter bars, which is not a safe mid-deploy change. Reverting clears this blocker and its siblings at once, and the feature can re-land with an idempotent, intent-guarded open.

    Assigned: @Gonals and @daledah (approving reviewers of the causing PR) — already assigned by melvin-bot, no change made. The PR author is a bot, so no author assignment.
    Labels: No changes. DeployBlockerCash is kept (an App PR caused this and the fix lands in Expensify/App); DeployBlocker is not present, so there is nothing to remove.

    📋 Detailed Analysis

    Evidence

    • Reproducible on staging 9.4.91-0, not on production, so the cause is in the current Deploy Checklist: New Expensify 2026-09-21 (Expensify/App#101773).

    • Before PR Show up to three report fields per row and edit them inline #100735, tapping a list report field navigated to DynamicEditReportFieldPage — a full screen, with no popover that could dismiss itself. That PR replaced the report-field rows with inline inputs and made a list field open the option list in a popover instead (ReportFieldInlineInput.tsx#L150-L154, #L199-L222). The symptom described here cannot exist without that change.

    • The reported threshold is exact, and it maps to a constant the same PR introduced:

      src/CONST/index.ts#L7099-L7100

      /** Below this many options, a report field list is short enough to scan without a search input */
      REPORT_FIELD_LIST_SEARCH_THRESHOLD: 8,

      ReportFieldInlineInput.tsx#L154

      const shouldShowSearchInput = enabledOptions.length >= CONST.REPORT_FIELD_LIST_SEARCH_THRESHOLD;

      At exactly 8 enabled values the dropdown starts rendering a search input, and the search input is what raises the Android soft keyboard inside the open dropdown. Below 8 no keyboard is ever raised by the dropdown, which is why 7 values behave correctly.

    Verification

    Root Cause

    The dropdown open is a toggle, and at ≥ 8 options the open becomes asynchronous and re-entrant, so a second toggle closes what the first just opened.

    1. FilterPopupButton uses one toggleOverlay for everything — the trigger's onPress, the popover's onClose, and the closeOverlay handed to the content — and routes the open through KeyboardUtils.dismissKeyboardAndExecute: FilterPopupButton.tsx#L81-L112. A toggle is only correct if every trigger fires exactly once.
    2. On Android, dismissKeyboardAndExecute runs the callback synchronously only when no keyboard is up; otherwise it defers it behind a keyboardDidHide listener, and on the e.height !== 0 branch it returns without removing that listener, so a stale callback can fire on a later keyboard hide: src/utils/keyboard/index.android.ts#L50-L69.
    3. With ≥ 8 values the dropdown renders the SelectionList search input, which auto-focuses 300ms after mount unless disableAutoFocus is passed — and EditReportFieldDropdown does not pass it: SelectionList/components/TextInput.tsx#L121-L136. So the soft keyboard comes up while the dropdown is open, flipping the module-level isVisible flag to true and putting every subsequent open into the deferred, listener-based path.
    4. The trigger can fire onPress more than once per tap: on native BaseTextInput wires the caller's onPress to both the wrapper pressable and the inner input's onPressOut (BaseTextInput/implementation/index.native.tsx#L441-L442), and ReportFieldInlineInput additionally binds the same handler to onSubmitEditing (#L216-L218). Once one of those toggles is deferred behind a keyboard event, it lands after the dropdown is already open and toggles it straight back shut — the reported "closes immediately after opening", and the "takes a few attempts" flakiness, since the outcome depends on the keyboard-event race.

    For contrast, DatePicker — the closest analogue, also a TextInput with disableKeyboard opening a popover — does not misbehave because its open is idempotent and intent-guarded (setPickerVisibility(true) plus an openIntentRef), not a toggle: DatePicker/index.tsx.

    If a roll-forward is preferred over a revert, the minimal fix is:

    • Split toggleOverlay in FilterPopupButton into idempotent openOverlay/closeOverlay, pass openOverlay as the trigger's onPress and the real closeOverlay as onClose and to PopoverComponent, and guard the deferred open with an intent ref the way DatePicker does.
    • Stop binding the same handler to both onPress and onSubmitEditing on the list trigger in ReportFieldInlineInput.
    • Optionally pass disableAutoFocus in EditReportFieldDropdown's textInputOptions when it is rendered inside the inline dropdown, so the dropdown never raises the keyboard on open.

    Unverified: I could not run this on an Android device, so which of the extra triggers wins the race (the inner onPressOut versus onSubmitEditing versus a stale deferred callback) is inferred from the code rather than observed. The exact 8-value threshold matching REPORT_FIELD_LIST_SEARCH_THRESHOLD, and the defect itself — a toggle used as an open action, reachable from several triggers and deferred asynchronously whenever a keyboard is up — hold regardless.

  8. Gonals commented on Sep 22, 2026

    @Gonals
    Contributor

    PR reverted

  9. IuliiaHerets commented on Sep 22, 2026

    @IuliiaHerets

    Xiaomi Redmi Note 10 / Android 12
    9.4.91-1
    Not repro

    Screenrecorder-2026-09-22-14-12-22-272.mp4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

BugSomething is broken. Auto assigns a BugZero manager.EngineeringReviewingHas a PR in review

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions