You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Due for payment 2026-10-22] [$175] Copy WS settings stuck on "Copy in progress..." modal while offline #103297
Version Number: 9.5.4-0 Reproducible in staging?: Yes Reproducible in production?: Yes If this was caught during regression testing, add the test name, ID and link from BrowserStack:#102985 Email or phone of affected tester (no customers):jose.sat94+10jul@gmail.com Issue reported by: Applause Internal Team Bug source: Pull Request QA execution Device used: MacBook Pro/13.7.8, Samsung Galaxy S21/Android 15, iPhone 13/18.6.2 App Component: Other
Action Performed:
Launch Expensify app
Log in with valid credentials
Create a Control workspace (Workspace A)
Enable Rules in Workspace A
Create at least one merchant rule in Workspace A
Create a Control workspace (Workspace C)
Turn off Rules in Workspace C
Click the ⋮ menu on Workspace A and select Copy settings
Select Workspace C, click Next, tick Merchant rules, and click Next
Click Copy settings
The same when go offline after step 7.
Expected Result:
The copy settings process completes successfully, and Workspace C has Rules enabled with the merchant rule from Workspace A copied under Rules > Merchants.
Actual Result:
A "Copy in progress..." modal remains indefinitely with a loading spinner and the message "You can either wait for the process to finish or Concierge can let you know when it's done." The copy process does not complete.
changed the title [-]Offline - Copy WS settings stuck on "Copy in progress..." modal while offline[/-][+]Copy WS settings stuck on "Copy in progress..." modal while offline[/+]on Oct 7, 2026
Updated 2026-10-10: Updated to follow Design's direction from dannymcclain. When you're offline, the copy now goes straight to "Concierge will let you know".
Please re-state the problem that we are trying to solve in this issue.
If you start Copy settings while offline, the "Copy in progress..." spinner loads indefinitely. Instead, it should go straight to "Concierge will let you know", since the copy can't finish until you're back online.
What is the root cause of that problem?
The App always opens the modal on the loading step. It sets currentStep: 'loading' in optimistic data (CopyPolicySettings.ts:550-557). That step only ends when the server sets nvp_bulkPolicyCopySettings to complete or failed (CopyPolicySettingsProgressModal.tsx:33-48). Offline, the request is only queued, so that update can't arrive. The confirm page doesn't check the network before it starts the copy (CopyPolicySettingsConfirmPage.tsx:95).
What changes do you think we should make in order to solve the problem?
When the copy starts offline, do what "Let me know when it's done" does today (CopyPolicySettingsProgressModal.tsx:106-109). Queue the Concierge notification and open the complete step.
In CopyPolicySettingsConfirmPage.tsx, get isOffline from useNetwork() and pass it to copyPolicySettings.
Set the optimistic currentStep to COPY_SETTINGS_MODAL_STEP.COMPLETE when offline. Keep LOADING when online.
When offline, call requestCopyPolicySettingsNotification() right after the CopyPolicySettings write. The sequential queue sends it after the copy request when you reconnect, the same order as the online "Let me know" flow.
Keep everything else as it is, including the pending fields on the target workspaces and the failureData that resets currentStep and adds the error to the source workspace.
The modal then shows "Concierge will let you know" with "When the process is completed, Concierge will send you a message." It has "Go to Concierge" and "Dismiss" buttons, so you aren't stuck.
What specific scenarios should we cover in automated tests?
In tests/actions/CopyPolicySettingsTest.ts:
If isOffline is true, the optimistic currentStep is complete, and the target policy patch and pending fields are still set.
If isOffline is false, the optimistic currentStep is still loading.
If copyPolicySettings runs offline, it queues CopyPolicySettings_Notify with shouldOnlyNotifyOnFailure: false after CopyPolicySettings. If it runs online, it doesn't queue the notification.
What alternative solutions did you explore? (Optional)
Hide the modal when offline (my earlier proposal). Design prefers the Concierge step, because it tells you what will happen next.
Show "All set" when offline. This is wrong, because the copy hasn't run yet.
Switch steps inside the modal based on useNetwork(). This would also have to send the notification from a render path. It would also flip the step if you lose connection during an online copy. Deciding in the action when the copy starts avoids both problems.
Evidence that the offline notification works
In my 2026-10-08 web retest, I started the copy offline and clicked "Let me know when it's done" while still offline. After reconnecting, the queued copy ran. WS D got the merchant rule, and Concierge and #admins posted "copied 1 merchant rule from WS A". So queuing CopyPolicySettings_Notify offline, after the copy request, already works. This proposal makes that the automatic offline path.
Next Steps for Contributor+ team: To accept:@MelvinBot implement [this](https://github.com/Expensify/App/issues/103297#issuecomment-6035029774) to create a draft PR. To refine:@MelvinBot <your feedback> To reject: Explain why you are rejecting Melvin's proposal.
changed the title [-]Copy WS settings stuck on "Copy in progress..." modal while offline[/-][+][$175] Copy WS settings stuck on "Copy in progress..." modal while offline[/+]on Oct 7, 2026
Please re-state the problem that we are trying to solve in this issue.
When copying workspace settings (such as Merchant rules) to a workspace where Rules are disabled, the "Copy in progress..." modal remains stuck indefinitely with a loading spinner both online and while offline.
What is the root cause of that problem?
Missing Completion Transition in successData (CopyPolicySettings.ts):
In src/libs/actions/Policy/CopyPolicySettings.ts:544-565, buildCopyPolicySettingsData sets NVP_BULK_POLICY_COPY_SETTINGS to in-progress optimistically, but successData intentionally omits setting it to complete, relying exclusively on an asynchronous backend Pusher broadcast:
// Success intentionally omits this key — the backend transitions the bulk policy// copy NVP state to complete, which the UI uses to show the completion modal.
For settings like codingRules (merchant rules), the CopyPolicySettings API call executes and returns HTTP 200 successfully, but the backend does not trigger the bulk NVP worker nor emit a Pusher broadcast for nvp_bulkPolicyCopySettings. Because CopyPolicySettingsProgressModal.tsx:44-46 requires bulkPolicyCopySettings?.state === CONST.POLICY.COPY_SETTINGS_NVP_STATE.COMPLETE to transition to "All Set", the modal remains trapped in loading indefinitely.
Blocking Modal Lock While Offline:
When initiated offline, the write is queued in SequentialQueue, but CopyPolicySettingsProgressModal immediately mounts on WorkspacesListPage with isTitleLoading: true and no dismiss/cancel option (shouldShowCancelButton: false, cancelText: ''), trapping the user behind an indefinite spinner without connectivity.
What changes do you think we should make in order to solve the problem?
Ensure successData Transitions the Modal to Complete:
In src/libs/actions/Policy/CopyPolicySettings.ts, add the completion state to successData:
This guarantees that once the API request successfully resolves with HTTP 200, the UI transitions cleanly to "All set" without hanging on a missing backend Pusher echo.
Improve Offline Progress Modal Dismissal:
In src/pages/workspace/copyPolicySettings/CopyPolicySettingsProgressModal.tsx, enable dismissing the in-progress step via shouldShowCancelButton: true / cancel button or dismiss icon while offline/in-flight, ensuring the user is not locked behind a non-dismissible spinner when requests are queued offline.
What alternative solutions did you explore? (Optional)
Waiting solely for a backend/Auth fix:
Relying entirely on a server Pusher broadcast leaves the client vulnerable to missed socket messages and hanging spinners. Handling the API success transition in successData follows standard NewDot optimistic write patterns and makes the completion modal resilient.
@mallenexpensify, testing was needed. MelvinBot didn't include test steps, but the OP and I did. If testing weren't needed, I would have marked the PR "No QA".'
Update: I see what you mean: there's no reviewer checklist in the PR. That's really weird. I'm checking why.
Update: I think I forgot to post the PR reviewer checklist. Sorry about that.
Activity
applause-bot commentedon Oct 7, 2026
While Applause doesn't embed attachments for this bug, here are the links for quick view:
https://platform.applause.com/services/links/v1/external/07af7b371a65e768ceebc272dcdc3f09e8ee383f41edff7927c713b3426474b4
[-]Offline - Copy WS settings stuck on "Copy in progress..." modal while offline[/-][+]Copy WS settings stuck on "Copy in progress..." modal while offline[/+]MelvinBot commentedon Oct 7, 2026
Proposal
Updated 2026-10-10: Updated to follow Design's direction from
dannymcclain. When you're offline, the copy now goes straight to "Concierge will let you know".Please re-state the problem that we are trying to solve in this issue.
If you start Copy settings while offline, the "Copy in progress..." spinner loads indefinitely. Instead, it should go straight to "Concierge will let you know", since the copy can't finish until you're back online.
What is the root cause of that problem?
The App always opens the modal on the
loadingstep. It setscurrentStep: 'loading'in optimistic data (CopyPolicySettings.ts:550-557). That step only ends when the server setsnvp_bulkPolicyCopySettingstocompleteorfailed(CopyPolicySettingsProgressModal.tsx:33-48). Offline, the request is only queued, so that update can't arrive. The confirm page doesn't check the network before it starts the copy (CopyPolicySettingsConfirmPage.tsx:95).What changes do you think we should make in order to solve the problem?
When the copy starts offline, do what "Let me know when it's done" does today (CopyPolicySettingsProgressModal.tsx:106-109). Queue the Concierge notification and open the
completestep.CopyPolicySettingsConfirmPage.tsx, getisOfflinefromuseNetwork()and pass it tocopyPolicySettings.buildCopyPolicySettingsDataandcopyPolicySettings(CopyPolicySettings.ts:365, 576-592), add anisOfflineparameter. Then:currentSteptoCOPY_SETTINGS_MODAL_STEP.COMPLETEwhen offline. KeepLOADINGwhen online.requestCopyPolicySettingsNotification()right after theCopyPolicySettingswrite. The sequential queue sends it after the copy request when you reconnect, the same order as the online "Let me know" flow.failureDatathat resetscurrentStepand adds the error to the source workspace.The modal then shows "Concierge will let you know" with "When the process is completed, Concierge will send you a message." It has "Go to Concierge" and "Dismiss" buttons, so you aren't stuck.
What specific scenarios should we cover in automated tests?
In
tests/actions/CopyPolicySettingsTest.ts:isOfflineistrue, the optimisticcurrentStepiscomplete, and the target policy patch and pending fields are still set.isOfflineisfalse, the optimisticcurrentStepis stillloading.copyPolicySettingsruns offline, it queuesCopyPolicySettings_NotifywithshouldOnlyNotifyOnFailure: falseafterCopyPolicySettings. If it runs online, it doesn't queue the notification.What alternative solutions did you explore? (Optional)
useNetwork(). This would also have to send the notification from a render path. It would also flip the step if you lose connection during an online copy. Deciding in the action when the copy starts avoids both problems.Evidence that the offline notification works
In my 2026-10-08 web retest, I started the copy offline and clicked "Let me know when it's done" while still offline. After reconnecting, the queued copy ran. WS D got the merchant rule, and Concierge and #admins posted "copied 1 merchant rule from WS A". So queuing
CopyPolicySettings_Notifyoffline, after the copy request, already works. This proposal makes that the automatic offline path.Next Steps for Contributor+ team:
To accept:
@MelvinBot implement [this](https://github.com/Expensify/App/issues/103297#issuecomment-6035029774)to create a draft PR.To refine:
@MelvinBot <your feedback>To reject: Explain why you are rejecting Melvin's proposal.
melvin-bot commentedon Oct 7, 2026
Triggered auto assignment to Contributor-plus team member for initial proposal review - @QichenZhu (
External)[-]Copy WS settings stuck on "Copy in progress..." modal while offline[/-][+][$175] Copy WS settings stuck on "Copy in progress..." modal while offline[/+]melvin-bot commentedon Oct 7, 2026
Job added to Upwork: https://www.upwork.com/jobs/~022107764557003743890
camesenin commentedon Oct 7, 2026
Proposal
Please re-state the problem that we are trying to solve in this issue.
When copying workspace settings (such as Merchant rules) to a workspace where Rules are disabled, the "Copy in progress..." modal remains stuck indefinitely with a loading spinner both online and while offline.
What is the root cause of that problem?
successData(CopyPolicySettings.ts):In
src/libs/actions/Policy/CopyPolicySettings.ts:544-565,buildCopyPolicySettingsDatasetsNVP_BULK_POLICY_COPY_SETTINGStoin-progressoptimistically, butsuccessDataintentionally omits setting it tocomplete, relying exclusively on an asynchronous backend Pusher broadcast:codingRules(merchant rules), theCopyPolicySettingsAPI call executes and returnsHTTP 200successfully, but the backend does not trigger the bulk NVP worker nor emit a Pusher broadcast fornvp_bulkPolicyCopySettings. BecauseCopyPolicySettingsProgressModal.tsx:44-46requiresbulkPolicyCopySettings?.state === CONST.POLICY.COPY_SETTINGS_NVP_STATE.COMPLETEto transition to "All Set", the modal remains trapped inloadingindefinitely.When initiated offline, the write is queued in
SequentialQueue, butCopyPolicySettingsProgressModalimmediately mounts onWorkspacesListPagewithisTitleLoading: trueand no dismiss/cancel option (shouldShowCancelButton: false,cancelText: ''), trapping the user behind an indefinite spinner without connectivity.What changes do you think we should make in order to solve the problem?
successDataTransitions the Modal to Complete:In
src/libs/actions/Policy/CopyPolicySettings.ts, add the completion state tosuccessData:HTTP 200, the UI transitions cleanly to "All set" without hanging on a missing backend Pusher echo.In
src/pages/workspace/copyPolicySettings/CopyPolicySettingsProgressModal.tsx, enable dismissing the in-progress step viashouldShowCancelButton: true/ cancel button or dismiss icon while offline/in-flight, ensuring the user is not locked behind a non-dismissible spinner when requests are queued offline.What alternative solutions did you explore? (Optional)
Relying entirely on a server Pusher broadcast leaves the client vulnerable to missed socket messages and hanging spinners. Handling the API success transition in
successDatafollows standard NewDot optimistic write patterns and makes the completion modal resilient.Contributor details
Your Expensify account email: camesenin@gmail.com
Upwork Profile Link: https://www.upwork.com/freelancers/~0170d6b02e9440e604
melvin-bot commentedon Oct 7, 2026
✅ Contributor details stored successfully. Thank you for contributing to Expensify!
yuvrajangadsingh commentedon Oct 8, 2026
withdrawing this, it went up before the issue had the
Help Wantedlabel. will come back if the label is added.QichenZhu commentedon Oct 8, 2026
@MelvinBot I don't agree this is a backend issue. This is clearly a frontend issue because the bug only happens in offline mode.
36 remaining items
melvin-bot commentedon Oct 21, 2026
Triggered auto assignment to @mallenexpensify (
Awaiting Payment)melvin-bot commentedon Oct 21, 2026
Payment Summary
Resolving PRs:
Go straight to the Concierge step when copying workspace settings offline #103812
Reviewer: @QichenZhu owed $175 via NewDot
BugZero Checklist (@mallenexpensify)
mallenexpensify commentedon Oct 24, 2026
Payment Summary
Contributor+: @QichenZhu due $100 via NewDot
Tests weren't needed on the PR, standard amount is 50%
QichenZhu commentedon Oct 24, 2026
@mallenexpensify, testing was needed. MelvinBot didn't include test steps, but the OP and I did. If testing weren't needed, I would have marked the PR "No QA".'
Update: I see what you mean: there's no reviewer checklist in the PR. That's really weird. I'm checking why.
Update: I think I forgot to post the PR reviewer checklist. Sorry about that.