Skip to content

Locked BA-Locked bank account with Fix CTA does not appear in Home #102225

Open

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.93-1
Reproducible in staging?: Yes
Reproducible in production?: Yes
If this was caught during regression testing, add the test name, ID and link from BrowserStack: #99792 https://test-management.browserstack.com/projects/2219752/folder/57527100/test-cases/98911054
Email or phone of affected tester (no customers): [email protected]
Issue reported by: Applause Internal Team
Bug source: Pull Request QA execution
Device used: MacBook Air 26.6.2 Chrome, iPhone 15 iOS 26.6.1
App Component: User Settings

Action Performed:

  1. Log in with [email protected] in a fresh incognito window
  2. Navigate to the Home tab
  3. Under the "Time sensitive" section look for the "Fix" button beside the locked business bank account.
  4. Note that locked BA row blinks and disappears
  5. Go to Inbox tab and back to Home - now locked BA with Fix CTA is visible on Home page
  6. Refresh the browser - locked BA disappears

Expected Result:

Locked bank account with Fix CTA is displayed in Home tab

Actual Result:

Locked bank account with Fix CTA is not displayed in Home tab after sign in and after refresh

Workaround:

Unknown

Platforms:

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

Screenshots/Videos

Recording.6469.mp4

View all open jobs on GitHub

Applause Internal Information
Exported by: Svetlana Lazutkina
Bug ID: 7268478

Issue OwnerCurrent Issue Owner: @grgia

Activity

  1. added
    BugSomething is broken. Auto assigns a BugZero manager.
    on Sep 24, 2026
  2. applause-bot commented on Sep 24, 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/fa19b1773bd913f14c8ea36ca249b19ecd9486f0123f28a9c55aa821f2dafcb2

  3. MelvinBot commented on Sep 24, 2026

    @MelvinBot
    Contributor

    Proposal

    What is the root cause of that problem?

    The Home row is driven only by Onyx data: a policy's achAccount must have state === LOCKED and reimburser equal to the current user (useTimeSensitiveLockedBankAccount.ts:27-35).

    After every successful OpenApp or ReconnectApp call, the App sends SearchForTodos with null params (App.ts:515-517). Unlike OpenReport, OpenSearchPage, and OpenPaymentsPage, it does not send includeLockedBankAccounts: true. The likely result is that its response overwrites the locked account data, and the row disappears.

    This explains all three symptoms:

    1. Sign in: OpenApp data renders the row. Then the SearchForTodos response removes it (the "blink").
    2. Inbox → Home: the report screen sends OpenReport with includeLockedBankAccounts: true (Report/index.ts:1837-1839). That restores the data, so the row comes back.
    3. Refresh: the row renders from cache. Then ReconnectApp runs, followed by SearchForTodos, and the row is removed again.

    Prevent repeated bank account unlock requests from being sent did not cause this. It did not change the hook or its inputs, and the bug also reproduces in production. The bug most likely started with [No QA] Fire searchForTodos request after OpenApp/ReconnectApp (merged 2026-07-09).

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

    Send includeLockedBankAccounts: true and includePartiallySetupBankAccounts: true with SearchForTodos in loadPostDataForOpenOrReconnect. Also add a params type for SEARCH_FOR_TODOS in API/types.ts, which is currently null. This matches the pattern in OpenReport, OpenSearchPage, and OpenPaymentsPage.

    Caveat: I could not check the backend. An internal engineer should confirm two things:

    • SearchForTodos is the response that drops the locked achAccount or bankAccountList data.
    • The backend honors these flags on SearchForTodos.

    If the backend ignores the flags, the fix belongs in the backend: SearchForTodos should stop overwriting bank account data. That change is outside the App repo.

    What alternative solutions did you explore? (Optional)

    Calling getPaymentMethods() from Home. I rejected it. It only refreshes bankAccountList, not the policy's achAccount, and it would race SearchForTodos.

    Investigation details

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


    view run

  4. added
    ExternalAdded to denote the issue can be worked on by a contributor
    on Sep 24, 2026
  5. melvin-bot commented on Sep 24, 2026

    @melvin-bot

    Triggered auto assignment to Contributor-plus team member for initial proposal review - @dmkt9 (External)

  6. changed the title [-]Locked BA-Locked bank account with Fix CTA does not appear in Home[/-] [+][$175] Locked BA-Locked bank account with Fix CTA does not appear in Home[/+] on Sep 24, 2026
  7. melvin-bot commented on Sep 24, 2026

    @melvin-bot

    Unable to auto-create job on Upwork. The BZ team member should create it manually for this issue.

  8. Mateidslx commented on Sep 25, 2026

    @Mateidslx

    Contributor details
    Your Expensify account email: [email protected]
    Upwork Profile Link: https://www.upwork.com/freelancers/~01b6f7f3d5061f49d9

    Proposal

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

    On the Home tab, under the "Time sensitive" section, the locked bank account row with the "Fix" CTA blinks on initial load and disappears. Navigating to the Inbox/Report tab and returning to Home makes the row reappear, but refreshing the page causes it to disappear again.

    What is the root cause of that problem?

    The Time Sensitive locked bank account widget is driven by Onyx data via useTimeSensitiveLockedBankAccount.ts (lines 27–35), which inspects policy.achAccount with state === CONST.BANK_ACCOUNT.STATE.LOCKED and personal accounts in ONYXKEYS.BANK_ACCOUNT_LIST.

    When the user first opens or reconnects the app, OpenApp/ReconnectApp fetches data that includes the locked bank account. Immediately after OpenApp or ReconnectApp resolves successfully, the LoadPostDataForOpenOrReconnect middleware executes loadPostDataForOpenOrReconnect() in src/libs/actions/App.ts (lines 515–517), which calls:

    API.read(READ_COMMANDS.SEARCH_FOR_TODOS, null);

    Unlike other read commands like OpenReport, OpenSearchPage, and OpenPaymentsPage, SearchForTodos is sent with null parameters rather than requesting bank account information (includeLockedBankAccounts: true, includePartiallySetupBankAccounts: true). When the SearchForTodos response arrives, it updates Onyx without the locked bank account data, overriding the data populated by OpenApp/ReconnectApp and causing the widget to disappear.

    When the user navigates to a report, OpenReport is sent with includeLockedBankAccounts: true (src/libs/actions/Report/index.ts:1837-1839), repopulating the bank account data in Onyx and making the widget reappear. Refreshing the browser runs ReconnectApp followed again by SearchForTodos with null, reproducing the disappearance.

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

    1. Define Parameter Type:
      Create src/libs/API/parameters/SearchForTodosParams.ts:

      type SearchForTodosParams = {
          includePartiallySetupBankAccounts?: boolean;
          includeLockedBankAccounts?: boolean;
      };
      
      export default SearchForTodosParams;
    2. Update API Types:
      In src/libs/API/types.ts:

      • Import SearchForTodosParams from './parameters/SearchForTodosParams'.
      • Update READ_COMMANDS.SEARCH_FOR_TODOS parameter definition from null to SearchForTodosParams:
        [READ_COMMANDS.SEARCH_FOR_TODOS]: SearchForTodosParams;
    3. Update Action in src/libs/actions/App.ts:
      In loadPostDataForOpenOrReconnect():

      function loadPostDataForOpenOrReconnect() {
          API.read(READ_COMMANDS.SEARCH_FOR_TODOS, {
              includeLockedBankAccounts: true,
              includePartiallySetupBankAccounts: true,
          });
      }
    4. Update Unit Tests:
      In tests/actions/AppTest.ts (lines 190 and 203):
      Update the assertion:

      expect(read).toHaveBeenCalledWith(READ_COMMANDS.SEARCH_FOR_TODOS, {
          includeLockedBankAccounts: true,
          includePartiallySetupBankAccounts: true,
      });

    What alternative solutions did you explore? (Optional)

    • Calling PaymentMethods.getPaymentMethods() from the Home screen on mount: rejected because getPaymentMethods only fetches bankAccountList, not workspace achAccount, and would introduce a redundant network call and race conditions against SearchForTodos.
  9. melvin-bot commented on Sep 25, 2026

    @melvin-bot

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

  10. ashusatyarthi-wq commented on Sep 27, 2026

    @ashusatyarthi-wq

    Proposal

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

    On the Home tab under the "Time sensitive" section, the locked bank account row with the "Fix" CTA briefly appears upon opening or reconnecting the app and then blinks and disappears. When navigating to an expense/report and returning to Home, the row reappears, but refreshing the page causes it to disappear again.

    What is the root cause of that problem?

    The "Time sensitive" locked bank account row is computed by useTimeSensitiveLockedBankAccount.ts (lines 27–56), which inspects policy.achAccount for state === CONST.BANK_ACCOUNT.STATE.LOCKED (matching the current user's primary login) and personal accounts in ONYXKEYS.BANK_ACCOUNT_LIST.

    1. Initial Load / Reconnect:
      When the app opens or reconnects, OpenApp or ReconnectApp delivers initial Onyx data that includes the locked bank account information.
    2. SearchForTodos drops the bank account data:
      Immediately after OpenApp/ReconnectApp completes, LoadPostDataForOpenOrReconnect middleware executes loadPostDataForOpenOrReconnect() in src/libs/actions/App.ts (lines 514–517):
      function loadPostDataForOpenOrReconnect() {
          API.read(READ_COMMANDS.SEARCH_FOR_TODOS, null);
      }
      Notice that SEARCH_FOR_TODOS is sent with null parameters ([READ_COMMANDS.SEARCH_FOR_TODOS]: null in src/libs/API/types.ts:1637). Because includeLockedBankAccounts and includePartiallySetupBankAccounts are not requested, the server response for SearchForTodos returns Onyx updates that omit or overwrite the locked bank account data, causing the widget to disappear immediately after rendering (the "blink").
    3. Navigating to a report restores the data:
      When opening any report, OpenReport explicitly sends:
      includePartiallySetupBankAccounts: true,
      includeLockedBankAccounts: true,
      in src/libs/actions/Report/index.ts (lines 1837–1839). This repopulates the locked bank account data in Onyx, causing the Home row to reappear when the user navigates back.
    4. Refreshing the page repeats the cycle:
      Refreshing renders the cached data, but runs ReconnectApp followed by SearchForTodos with null, wiping the row once more.

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

    1. Create Parameters Type for SearchForTodos:
      Create src/libs/API/parameters/SearchForTodosParams.ts:

      type SearchForTodosParams = {
          includePartiallySetupBankAccounts?: boolean;
          includeLockedBankAccounts?: boolean;
      };
      
      export default SearchForTodosParams;
    2. Update src/libs/API/types.ts:
      Import SearchForTodosParams and update READ_COMMANDS.SEARCH_FOR_TODOS:

      [READ_COMMANDS.SEARCH_FOR_TODOS]: SearchForTodosParams;
    3. Pass Flags in src/libs/actions/App.ts:
      In loadPostDataForOpenOrReconnect():

      function loadPostDataForOpenOrReconnect() {
          API.read(READ_COMMANDS.SEARCH_FOR_TODOS, {
              includeLockedBankAccounts: true,
              includePartiallySetupBankAccounts: true,
          });
      }
    4. Update Unit Tests in tests/actions/AppTest.ts:
      Update lines 189 and 202 to assert that READ_COMMANDS.SEARCH_FOR_TODOS is invoked with the expected parameters:

      expect(read).toHaveBeenCalledWith(READ_COMMANDS.SEARCH_FOR_TODOS, {
          includeLockedBankAccounts: true,
          includePartiallySetupBankAccounts: true,
      });

    What alternative solutions did you explore? (Optional)

    • Triggering PaymentMethods.getPaymentMethods() from Home:
      Rejected because getPaymentMethods() only refreshes personal bankAccountList and does not refresh workspace achAccount. It would also trigger redundant network requests and create a race condition against SearchForTodos.
  11. melvin-bot commented on Sep 29, 2026

    @melvin-bot

    @dmkt9 Eep! 4 days overdue now. Issues have feelings too...

  12. 3 remaining items

  13. melvin-bot commented on Oct 5, 2026

    @melvin-bot

    Triggered auto assignment to @grgia, see https://stackoverflow.com/c/expensify/questions/7972 for more details.

  14. melvin-bot commented on Oct 8, 2026

    @melvin-bot

    @grgia @dmkt9 this issue was created 2 weeks ago. Are we close to approving a proposal? If not, what's blocking us from getting this issue assigned? Don't hesitate to create a thread in #expensify-open-source to align faster in real time. Thanks!

  15. melvin-bot commented on Oct 8, 2026

    @melvin-bot

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

  16. melvin-bot commented on Oct 12, 2026

    @melvin-bot

    @grgia Still overdue 6 days?! Let's take care of this!

  17. melvin-bot commented on Oct 14, 2026

    @melvin-bot

    @grgia 8 days overdue is a lot. Should this be a Weekly issue? If so, feel free to change it!

  18. grgia commented on Oct 15, 2026

    @grgia
    Contributor

    Backend bug, not the flags. SearchForTodos resolves the workspace bank account differently from OpenApp, and that merge hides the row. Fixing in https://github.com/Expensify/Auth/pull/25276, no FE PR needed. @dmkt9

  19. added
    InternalRequires API changes or must be handled by Expensify staff
    and removed
    ExternalAdded to denote the issue can be worked on by a contributor
    on Oct 19, 2026
  20. changed the title [-][$175] Locked BA-Locked bank account with Fix CTA does not appear in Home[/-] [+]Locked BA-Locked bank account with Fix CTA does not appear in Home[/+] on Oct 19, 2026
  21. grgia commented on Oct 19, 2026

    @grgia
    Contributor
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.DailyKSv2InternalRequires API changes or must be handled by Expensify staff

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions