Skip to content

[Due for payment 2026-06-17] [$250] Currency RHP doesn't open when pressing "Update workspace currency" #93062

Closed

Description

@m-natarajan

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.1-4
Reproducible in staging?: Y
Reproducible in production?: N
If this was caught during regression testing, add the test name, ID and link from BrowserStack:
Email or phone of affected tester (no customers):
Logs: https://stackoverflow.com/c/expensify/questions/4856
Expensify/Expensify Issue URL:
Issue reported by: @bernhardoj
Slack conversation (hyperlinked to channel name): #Expensify Bugs

Action Performed:

Prerequisite: Have a workspace with non-supported currency for business bank account

  1. Go to the workspace workflows page
  2. Scroll down to the Payment section
  3. Press "+ Add bank account"
  4. Press "Update workspace currency"

Expected Result:

Currency RHP opens to update the currency

Actual Result:

No action is happening when clicking on "Update workspace currency",

Workaround:

Unknown

Platforms:

Select the officially supported platforms where the issue was reproduced:

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

Screenshots/Videos

web.mp4
Recording.2981.mp4

View all open jobs on GitHub

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

Activity

  1. added
    DeployBlockerCashThis issue or pull request should block deployment
    BugSomething is broken. Auto assigns a BugZero manager.
    on Jun 9, 2026
  2. melvin-bot commented on Jun 9, 2026

    @melvin-bot

    Triggered auto assignment to @pecanoro (DeployBlockerCash), see https://stackoverflowteams.com/c/expensify/questions/9980/ for more details.

  3. melvin-bot commented on Jun 9, 2026

    @melvin-bot

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

  4. github-actions commented on Jun 9, 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. MelvinBot commented on Jun 9, 2026

    @MelvinBot
    Contributor

    Proposal

    What is the root cause of that problem?

    The "Update workspace currency" button does fire its confirm handler — but the navigation it triggers gets silently undone by the global confirm modal's back-navigation handling.

    The handler confirmCurrencyChangeAndHideModal navigates deferred, via setNavigationActionToMicrotaskQueue (a microtask + requestAnimationFrame).

    The confirm modal is opened through useConfirmModal, which sets shouldHandleNavigationBack: true. When such a modal hides, Modal.hideModal schedules a window.history.back() on setTimeout(0), guarded so it only fires if no navigation has pushed a new history entry in the meantime (line 72).

    That guard assumes the confirm callback navigates synchronously. Because the Workflows handler defers its navigation past the setTimeout(0), the guard sees no new history entry, so history.back() runs and cancels the forward navigation → nothing happens.

    Why the sibling flow works, and why this is staging-only

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

    In confirmCurrencyChangeAndHideModal, navigate directly (synchronously inside the .then()) instead of wrapping it in setNavigationActionToMicrotaskQueue — exactly as the working invoice section does. This restores the synchronous-navigation contract the modal's guard relies on.

    Before merging, confirm this doesn't reintroduce the original navigation issue from #76691 that the microtask wrapper was added for. The invoice sibling navigating directly to the identical route suggests direct navigation is safe.

    What alternative solutions did you explore? (Optional)

    • If a revert is preferred for the deploy block, identify and revert the recent modal back-navigation change that introduced the guarded deferred history.back() in Modal/index.tsx (likely the modal refactor merged into this staging cut). The targeted one-line fix above is lower-risk.
    Confidence

    High on the failure mechanism and code location (verified against Modal/index.tsx:63-80, useConfirmModal.ts:17, and the working invoice sibling). Medium on exactly which recent modal-infra PR is the trigger — worth a quick runtime confirm (e.g. a breadcrumb in the rAF callback + watching popstate).


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

  6. OSBotify commented on Jun 9, 2026

    @OSBotify
    Contributor

    🔍 Investigation Summary

    Classification: Frontend bug
    Causing PR: #77919 - "Refactor ConfirmModal usage to useConfirmModal in workspace accounting and general pages (Part 1)" by @thelullabyy (Medium confidence)
    Related Issues: None

    Recommendation: NEEDS INVESTIGATION

    The root cause is not fully confirmed through static analysis alone, but PR #77919 is the strongest candidate — it is the only staging-only change that directly modified ConfirmModalWrapper.tsx and ModalContext.tsx, which are used by WorkspaceWorkflowsPage's confirm modal flow. The author and reviewers should verify whether the new isConfirmLoading !== undefined check or the resolveModal addition interacts incorrectly with the "Update workspace currency" flow.

    Assigned: @thelullabyy (PR author), @ZhenjaHorbach @roryabraham (approving reviewers) from highest-confidence causing PR
    Labels: DeployBlockerCash kept (frontend App PR is suspected cause, staging-only)

    📋 Detailed Analysis

    Evidence

    const handleConfirm = () => {
      setCloseAction(ModalActions.CONFIRM);
      if (props.isConfirmLoading !== undefined) {
        // NEW in PR 77919
        setIsConfirmLoading(true);
        resolveModal({ action: ModalActions.CONFIRM });
      } else {
        setIsVisible(false); // Only this path existed before
      }
    };
    • For WorkspaceWorkflowsPage, showConfirmModal is called without isConfirmLoading, so props.isConfirmLoading === undefined, and the else branch should run. However, there may be subtle interactions with the newly-added resolveModal mechanism or state management.
    • PR Refactor ConfirmModal usage to useConfirmModal in workspace accounting and general pages (Part 1) #77919 also changed WorkspaceOverviewPage.tsx to pass isConfirmLoading: isPendingDelete where isPendingDelete can be false (not undefined). When isConfirmLoading={false} is passed, false !== undefined is true, which takes the resolveModal path — this means the confirm button keeps the modal open and shows a spinner even when no deletion is pending. This could be a related issue.
    • The bug is reproducible on Windows: Chrome and MacOS: Chrome/Safari (web), not iOS/Android. This suggests the issue may relate to web-specific modal behavior.
    • The bug does NOT reproduce on production, which means it was introduced by one of the staging-only PRs. PR Refactor ConfirmModal usage to useConfirmModal in workspace accounting and general pages (Part 1) #77919 (merged 2026-06-05) is the only staging PR touching the core confirm modal infrastructure.

    Verification

    Root Cause

    The WorkspaceWorkflowsPage uses useConfirmModal to show a "Workspace currency not supported" confirm modal when "+ Add bank account" is pressed. When the user clicks "Update workspace currency" (the confirm button), the expected flow is:

    1. ConfirmModalWrapper.handleConfirm() sets isVisible = false
    2. Modal hides, handleModalHide() fires, calls closeModal({action: CONFIRM})
    3. Promise resolves, .then() runs confirmCurrencyChangeAndHideModal()
    4. Navigation.setNavigationActionToMicrotaskQueue(() => Navigation.navigate(ROUTES.WORKSPACE_OVERVIEW_CURRENCY...)) is called

    PR #77919 introduced new state (isConfirmLoading, resolveModal) into this flow. While theoretically the else branch should still run for this case, there may be a timing or state issue introduced by the PR that breaks the promise resolution or navigation in the web context. The author/reviewers of PR #77919 are best positioned to confirm whether the changes interact unexpectedly with the WorkspaceWorkflowsPage confirm modal flow.

    Recommended action: Revert PR #77919 and verify whether the bug is fixed. If reverting is too disruptive (due to other PRs depending on the new isConfirmLoading mechanism), a targeted fix should be applied to ensure ConfirmModalWrapper.handleConfirm closes the modal correctly when props.isConfirmLoading is not passed.

  7. 22 remaining items

  8. added
    Awaiting PaymentAuto-added when associated PR is deployed to production
    and removed on Jun 15, 2026
  9. melvin-bot commented on Jun 16, 2026

    @melvin-bot

    Triggered auto assignment to @mallenexpensify (Awaiting Payment)

  10. melvin-bot commented on Jun 16, 2026

    @melvin-bot

    Payment Summary

    Upwork Job

    BugZero Checklist (@mallenexpensify)

    • 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/2064410233541249702/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
  11. mallenexpensify commented on Jun 18, 2026

    @mallenexpensify
    Contributor

    Payment Summary

    Contributor+: @ZhenjaHorbach due $250 via NewDot

    ^ Test case created. Thx

  12. ZhenjaHorbach commented on Jun 18, 2026

    @ZhenjaHorbach
    Contributor

    Payment Summary

    Contributor: @thelullabyy due $250 via Upwork Contributor+: @ZhenjaHorbach due $250 via NewDot

    @thelullabyy can you please accept the job below? Please reply here and tag me once you have. If you're not sent an offer in Upwork when you're assigned to an issue, please tag me. If an Upwork job exists, please submit a proposal. https://www.upwork.com/jobs/~022064410233541249702

    ^ Test case created. Thx

    @mallenexpensify
    I suppose only I need a payment
    Since Melvin was the author of the PR

  13. thelullabyy commented on Jun 18, 2026

    @thelullabyy
    Contributor

    No need payment for me here

  14. mallenexpensify commented on Jun 19, 2026

    @mallenexpensify
    Contributor

    Thx, payment summary updated

  15. garrettmknight commented on Jun 19, 2026

    @garrettmknight
    Contributor

    $250 approved for @ZhenjaHorbach

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 productionBugSomething 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