Skip to content

fix: KYC flow doesn't trigger after adding bank account when paying another user#92154

Open
samranahm wants to merge 13 commits into
Expensify:mainfrom
samranahm:91873/trigger-kyc-after-adding-account
Open

fix: KYC flow doesn't trigger after adding bank account when paying another user#92154
samranahm wants to merge 13 commits into
Expensify:mainfrom
samranahm:91873/trigger-kyc-after-adding-account

Conversation

@samranahm
Copy link
Copy Markdown
Contributor

@samranahm samranahm commented May 31, 2026

Explanation of Change

When paying another user with a personal bank account, the KYC flow wasn't triggering after adding the account. The cause was AccountFlowEntryPoint calling clearPersonalBankAccount() on mount, which wiped the onSuccessFallbackRoute that the pay flow sets before this screen and that AddPersonalBankAccountPage reads after it, so the app could no longer continue into KYC.

To fix this we update the reset on unmount instead of mount, so the route stays available while the flow is open and is cleared only when the user finishes setup or goes back.

Fixed Issues

$ #91873
PROPOSAL: #91873 (comment)

Tests

Precondition:

  • The user does not have a personal bank account connected.

Test 01

  1. Start a 1:1 conversation with another user.
  2. Press the + button and select Pay [User].
  3. On the amount screen, tap the currency selector and choose USD, then enter any amount and continue.
  4. Verify that the payment method dropdown displays "Pay with personal account".
  5. Press "Pay with personal account" and verify that the bank account connection flow starts.
  6. Add a bank account using either Plaid or manual entry, then press Continue on the "Bank account added" page.
  7. Verify the KYC verification flow is triggered (confirm additional details to process the payment)

Test 02

  1. Go to Settings > Wallet and press "Add bank account".
  2. Select "Get reimbursed", then choose United States as the country.
  3. Enter the bank account details (Plaid or manual entry) and press Continue.
  4. On the "Let's double-check..." page, press Confirm and verify the bank account is added (the "Bank account added" page is shown).
  5. Press Continue and verify that the user is returned to the Wallet page, the KYC flow is not triggered and the additional details page does not open.
  • Verify that no errors appear in the JS console

Offline tests

N/A – Bank account setup can only be run while online.

QA Steps

Same as test

// TODO: These must be filled out, or the issue title must include "[No QA]."

  • Verify that no errors appear in the JS console

PR Author Checklist

  • I linked the correct issue in the ### Fixed Issues section above
  • I wrote clear testing steps that cover the changes made in this PR
    • I added steps for local testing in the Tests section
    • I added steps for the expected offline behavior in the Offline steps section
    • I added steps for Staging and/or Production testing in the QA steps section
    • I added steps to cover failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
    • I tested this PR with a High Traffic account against the staging or production API to ensure there are no regressions (e.g. long loading states that impact usability).
  • I included screenshots or videos for tests on all platforms
  • I ran the tests on all platforms & verified they passed on:
    • Android: Native
    • Android: mWeb Chrome
    • iOS: Native
    • iOS: mWeb Safari
    • MacOS: Chrome / Safari
  • I verified there are no console errors (if there's a console error not related to the PR, report it or open an issue for it to be fixed)
  • I followed proper code patterns (see Reviewing the code)
    • I verified that any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. toggleReport and not onIconClick)
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing.
    • I verified any copy / text shown in the product is localized by adding it to src/languages/* files and using the translation method
    • I verified all numbers, amounts, dates and phone numbers shown in the product are using the localization methods
    • I verified any copy / text that was added to the app is grammatically correct in English. It adheres to proper capitalization guidelines (note: only the first word of header/labels should be capitalized), and is either coming verbatim from figma or has been approved by marketing (in order to get marketing approval, ask the Bug Zero team member to add the Waiting for copy label to the issue)
    • I verified proper file naming conventions were followed for any new files or renamed files. All non-platform specific files are named after what they export and are not named "index.js". All platform-specific files are named for the platform the code supports as outlined in the README.
    • I verified the JSDocs style guidelines (in STYLE.md) were followed
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I followed the guidelines as stated in the Review Guidelines
  • I tested other components that can be impacted by my changes (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar are working as expected)
  • I verified all code is DRY (the PR doesn't include any logic written more than once, with the exception of tests)
  • I verified any variables that can be defined as constants (ie. in CONST.ts or at the top of the file that uses the constant) are defined as such
  • I verified that if a function's arguments changed that all usages have also been updated correctly
  • If any new file was added I verified that:
    • The file has a description of what it does and/or why is needed at the top of the file if the code is not self explanatory
  • If a new CSS style is added I verified that:
    • A similar style doesn't already exist
    • The style can't be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))
  • If new assets were added or existing ones were modified, I verified that:
    • The assets are optimized and compressed (for SVG files, run npm run compress-svg)
    • The assets load correctly across all supported platforms.
  • If the PR modifies code that runs when editing or sending messages, I tested and verified there is no unexpected behavior for all supported markdown - URLs, single line code, code blocks, quotes, headings, bold, strikethrough, and italic.
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.
  • If the PR modifies a component or page that can be accessed by a direct deeplink, I verified that the code functions as expected when the deeplink is used - from a logged in and logged out account.
  • If the PR modifies the UI (e.g. new buttons, new UI components, changing the padding/spacing/sizing, moving components, etc) or modifies the form input styles:
    • I verified that all the inputs inside a form are aligned with each other.
    • I added Design label and/or tagged @Expensify/design so the design team can review the changes.
  • If a new page is added, I verified it's using the ScrollView component to make it scrollable when more elements are added to the page.
  • I added unit tests for any new feature or bug fix in this PR to help automatically prevent regressions in this user flow.
  • If the main branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to the Test steps.

Screenshots/Videos

Android: Native
Android.Native.mp4
Android: mWeb Chrome
Android.mWeb.Chrome.mp4
iOS: Native
IOS.Native.mp4
iOS: mWeb Safari
IOS.mWeb.Safari.mp4
MacOS: Chrome / Safari
macOS.Chrome.mp4

Copilot AI review requested due to automatic review settings May 31, 2026 17:13
@samranahm samranahm requested review from a team as code owners May 31, 2026 17:13
@melvin-bot melvin-bot Bot requested review from Eskalifer1 and flaviadefaria May 31, 2026 17:13
@melvin-bot
Copy link
Copy Markdown

melvin-bot Bot commented May 31, 2026

@Eskalifer1 Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button]

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adjusts the personal bank account clearing logic so that, when entering the international deposit account flow, routing-related data is preserved while transient UI/error state is reset.

Changes:

  • Added a shouldPreserveRoutingData parameter to clearPersonalBankAccount that, when true, only clears loading/error/success flags instead of wiping the entire Onyx key.
  • Updated AccountFlowEntryPoint to call clearPersonalBankAccount(true) to retain routing data on mount.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/libs/actions/BankAccounts.ts Adds optional preserve flag to selectively merge-clear transient state instead of nulling the whole bank account key.
src/pages/settings/Wallet/InternationalDepositAccount/subPages/AccountFlowEntryPoint.tsx Passes true to preserve routing data when clearing on entry.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/libs/actions/BankAccounts.ts Outdated
Comment thread src/libs/actions/BankAccounts.ts Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d1e59aa03c

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@codecov
Copy link
Copy Markdown

codecov Bot commented May 31, 2026

Codecov Report

✅ Changes either increased or maintained existing code coverage, great job!

Files with missing lines Coverage Δ
src/libs/actions/BankAccounts.ts 15.30% <100.00%> (+3.91%) ⬆️
...lDepositAccount/subPages/AccountFlowEntryPoint.tsx 0.00% <0.00%> (ø)
... and 365 files with indirect coverage changes

Comment thread src/libs/actions/BankAccounts.ts Outdated
Comment on lines +294 to +300
function clearPersonalBankAccount(shouldPreserveRoutingData = false) {
/**
* Clears personal bank account state. Pass `shouldPreserveAccountData=true` to only clear UI/error
* fields while keeping routing and context fields intact.
*/
function clearPersonalBankAccount(shouldPreserveAccountData = false) {
clearPlaid();
if (shouldPreserveRoutingData) {
if (shouldPreserveAccountData) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should do it this way, because we currently have cleanup logic throughout the entire project, so I think we should keep it.

I think that when we added the cleanup logic, we simply forgot that onSuccessFallbackRoute shouldn’t be cleaned up, so I think we should just fix that. If we leave it as it is now, we’ll definitely get regressions and incorrect behavior.

I think it should look something like this:

function clearPersonalBankAccount(preservedData?: Partial<PersonalBankAccount>) {
    clearPlaid();
    Onyx.set(ONYXKEYS.PERSONAL_BANK_ACCOUNT, preservedData ?? null);
    Onyx.set(ONYXKEYS.FORMS.PERSONAL_BANK_ACCOUNT_FORM_DRAFT, null);
    clearPersonalBankAccountSetupType();
}

And pass it like this:

   useEffect(() => {
        clearPersonalBankAccount(personalBankAccount?.onSuccessFallbackRoute ? {onSuccessFallbackRoute: personalBankAccount.onSuccessFallbackRoute} : undefined);
    }, []);

What do you think about that?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, that's much cleaner approach. Updated clearPersonalBankAccount to take preservedData?: Partial<PersonalBankAccount> with Onyx.set(preservedData ?? null), and the entry point now passes only onSuccessFallbackRoute. All other call sites stay as a full reset, so no behavior change of any kind there.

Copy link
Copy Markdown
Contributor

@Eskalifer1 Eskalifer1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fill out the Explanation of Change section

Let's also add some information to the Offline tests section, specifically “N/A” and the reason why there are no offline tests here

@Eskalifer1
Copy link
Copy Markdown
Contributor

I also think we should update the preconditions, specifically to specify that both users must have currency in USD:
Both users in USD currency default

Comment thread src/libs/actions/BankAccounts.ts Outdated
Co-authored-by: Eskalifer1 <artemkryt1800@gmail.com>
@samranahm
Copy link
Copy Markdown
Contributor Author

Thanks @Eskalifer1 for taking a look, I'm looking into this and will update the PR shortly.

@Eskalifer1
Copy link
Copy Markdown
Contributor

Sure! Let me know when this PR will be ready for next round of reviews!

@Eskalifer1
Copy link
Copy Markdown
Contributor

@codex review

@Eskalifer1
Copy link
Copy Markdown
Contributor

Eskalifer1 commented Jun 3, 2026

Reviewer Checklist

  • I have verified the author checklist is complete (all boxes are checked off).
  • I verified the correct issue is linked in the ### Fixed Issues section above
  • I verified testing steps are clear and they cover the changes made in this PR
    • I verified the steps for local testing are in the Tests section
    • I verified the steps for Staging and/or Production testing are in the QA steps section
    • I verified the steps cover any possible failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
  • I checked that screenshots or videos are included for tests on all platforms
  • I included screenshots or videos for tests on all platforms
  • I verified that the composer does not automatically focus or open the keyboard on mobile unless explicitly intended. This includes checking that returning the app from the background does not unexpectedly open the keyboard.
  • I verified tests pass on all platforms & I tested again on:
    • Android: HybridApp
    • Android: mWeb Chrome
    • iOS: HybridApp
    • iOS: mWeb Safari
    • MacOS: Chrome / Safari
  • If there are any errors in the console that are unrelated to this PR, I either fixed them (preferred) or linked to where I reported them in Slack
  • I verified proper code patterns were followed (see Reviewing the code)
    • I verified that any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. toggleReport and not onIconClick).
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing.
    • I verified any copy / text shown in the product is localized by adding it to src/languages/* files and using the translation method
    • I verified all numbers, amounts, dates and phone numbers shown in the product are using the localization methods
    • I verified any copy / text that was added to the app is grammatically correct in English. It adheres to proper capitalization guidelines (note: only the first word of header/labels should be capitalized), and is either coming verbatim from figma or has been approved by marketing (in order to get marketing approval, ask the Bug Zero team member to add the Waiting for copy label to the issue)
    • I verified proper file naming conventions were followed for any new files or renamed files. All non-platform specific files are named after what they export and are not named "index.js". All platform-specific files are named for the platform the code supports as outlined in the README.
    • I verified the JSDocs style guidelines (in STYLE.md) were followed
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I verified that this PR follows the guidelines as stated in the Review Guidelines
  • I verified other components that can be impacted by these changes have been tested, and I retested again (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar have been tested & I retested again)
  • I verified all code is DRY (the PR doesn't include any logic written more than once, with the exception of tests)
  • I verified any variables that can be defined as constants (ie. in CONST.ts or at the top of the file that uses the constant) are defined as such
  • If a new component is created I verified that:
    • A similar component doesn't exist in the codebase
    • All props are defined accurately and each prop has a /** comment above it */
    • The file is named correctly
    • The component has a clear name that is non-ambiguous and the purpose of the component can be inferred from the name alone
    • The only data being stored in the state is data necessary for rendering and nothing else
    • For Class Components, any internal methods passed to components event handlers are bound to this properly so there are no scoping issues (i.e. for onClick={this.submit} the method this.submit should be bound to this in the constructor)
    • Any internal methods bound to this are necessary to be bound (i.e. avoid this.submit = this.submit.bind(this); if this.submit is never passed to a component event handler like onClick)
    • All JSX used for rendering exists in the render method
    • The component has the minimum amount of code necessary for its purpose, and it is broken down into smaller components in order to separate concerns and functions
  • If any new file was added I verified that:
    • The file has a description of what it does and/or why is needed at the top of the file if the code is not self explanatory
  • If a new CSS style is added I verified that:
    • A similar style doesn't already exist
    • The style can't be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(theme.componentBG)
  • If the PR modifies code that runs when editing or sending messages, I tested and verified there is no unexpected behavior for all supported markdown - URLs, single line code, code blocks, quotes, headings, bold, strikethrough, and italic.
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.
  • If the PR modifies a component or page that can be accessed by a direct deeplink, I verified that the code functions as expected when the deeplink is used - from a logged in and logged out account.
  • If the PR modifies the UI (e.g. new buttons, new UI components, changing the padding/spacing/sizing, moving components, etc) or modifies the form input styles:
    • I verified that all the inputs inside a form are aligned with each other.
    • I added Design label and/or tagged @Expensify/design so the design team can review the changes.
  • If a new page is added, I verified it's using the ScrollView component to make it scrollable when more elements are added to the page.
  • For any bug fix or new feature in this PR, I verified that sufficient unit tests are included to prevent regressions in this flow.
  • If the main branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to the Test steps.
  • I have checked off every checkbox in the PR reviewer checklist, including those that don't apply to this PR.

Screenshots/Videos

Android: HybridApp
91873-android-native.mov
Android: mWeb Chrome
91873-android-web.mov
iOS: HybridApp
91873-ios-native.mov
iOS: mWeb Safari
91873-ios-web.mov
MacOS: Chrome / Safari
91873-web.mov

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 249dba04e1

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

useEffect(() => {
clearPersonalBankAccount();
}, []);
clearPersonalBankAccount(onSuccessFallbackRoute ? {onSuccessFallbackRoute} : undefined);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid reusing stale KYC fallback routes

When a user starts a Pay/KYC flow that sets onSuccessFallbackRoute and then backs out from this entry point, nothing in the entry-point back path clears PERSONAL_BANK_ACCOUNT; with this change, the stale fallback route is preserved instead of being wiped. If the same user later starts a normal Wallet > Add bank account flow, this line preserves that old route again, and AddPersonalBankAccountPage.exitFlow(true) will call continueSetup(...) instead of just returning to Wallet after success. Please only preserve the fallback for the active KYC-launched flow or clear it when the add-bank flow is abandoned.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is valid concern. I think we should find a solution to this. Although it's unlikely, it's still possible

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the logic to handle this edge case.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @samranahm, I don't really think that's the approach we want to take. After all, it makes more sense to clear the previous data on entry (which is much more stable) rather than on exit—plus, that's the logic that's been working for a very long time.

Can you check how onSuccessFallbackRoute was being cleared before this useEffect was added? Maybe that will give us a little more information.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MelvinBot How can this be fixed using this approach:

const [personalBankAccount, personalBankAccountResult] = useOnyx(ONYXKEYS.PERSONAL_BANK_ACCOUNT);

const isLoadingPersonalBankAccount = isLoadingOnyxValue(personalBankAccountResult)

useEffect(() => {
    if (isLoadingPersonalBankAccount) {
        return;
    }
    clearPersonalBankAccount(onSuccessFallbackRoute ? {onSuccessFallbackRoute} : undefined);
}, [isLoadingPersonalBankAccount]);

How was onSuccessFallbackRoute cleared before this useEffect was added?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Short version: onSuccessFallbackRoute has never had a dedicated clear — it's only ever wiped as a side effect of a full clearPersonalBankAccount() (which nulls the whole PERSONAL_BANK_ACCOUNT key). The entry-point mount clear was one of those full wipes, and it was the only thing protecting this screen from a stale route. So the isLoadingOnyxValue version fixes your deps concern, but on its own it does not close the stale-route hole chatgpt-codex-connector flagged in this thread — you need one more piece for that.


Q2 — How was onSuccessFallbackRoute cleared before this useEffect?

There is no route-specific clear anywhere in the codebase. The field's whole lifecycle:

So on main, entering this screen always nuked the entire object. That wipe is simultaneously (a) what kept a stale route from leaking into a later flow, and (b) what wiped the route this PR needs to keep — the bug. That's the tension: the moment you preserve the route on entry, you remove the thing that used to protect against stale routes. Note openPersonalBankAccountSetupView({}) — the generic Wallet → Add bank account entry — does not clear PERSONAL_BANK_ACCOUNT, which is precisely why chatgpt-codex-connector's scenario is reachable.

Q1 — Making the isLoadingOnyxValue approach work

It needs two pieces, not one.

Piece A — the entry-point effect (your version, corrected)
const [personalBankAccount, personalBankAccountResult] = useOnyx(ONYXKEYS.PERSONAL_BANK_ACCOUNT);
const isLoadingPersonalBankAccount = isLoadingOnyxValue(personalBankAccountResult);
const onSuccessFallbackRoute = personalBankAccount?.onSuccessFallbackRoute;

useEffect(() => {
    if (isLoadingPersonalBankAccount) {
        return;
    }
    clearPersonalBankAccount(onSuccessFallbackRoute ? {onSuccessFallbackRoute} : undefined);
    // eslint-disable-next-line react-hooks/exhaustive-deps
}, [isLoadingPersonalBankAccount]);

with clearPersonalBankAccount(preservedData?: Partial<PersonalBankAccount>) doing Onyx.set(PERSONAL_BANK_ACCOUNT, preservedData ?? null).

Two things to get right:

  • onSuccessFallbackRoute must be derived from personalBankAccount?.onSuccessFallbackRoute (your snippet references it but doesn't declare it).
  • The isLoadingOnyxValue guard is load-bearing, not cosmetic: useOnyx returns undefined while the key hydrates. Without the guard, the first render reads undefinedclearPersonalBankAccount(undefined)Onyx.set(..., null) → the route is wiped again (the original bug). Gating on hydration guarantees you read the real route before clearing, and keeping the dep array as [isLoadingPersonalBankAccount] only means the re-seed write won't re-trigger the effect (which is also what fixes your duplicate-clean concern). ✅
Piece B — close the stale-route hole (the concern this thread is about)

Piece A alone still preserves the route on every entry, so the abandon path you and chatgpt-codex-connector discussed is still open: set route → land here → preserve → back out (nothing clears it) → later generic flow reuses the stale route.

Since you (rightly) want to keep clear-on-entry rather than move it to unmount, the targeted fix is to wipe fully when the flow is actually abandoned at this entry screen. Wrap the back handler so leaving without proceeding does a full reset:

const handleBackButtonPress = () => {
    clearPersonalBankAccount(); // full wipe — abandoning the flow must not leave a stale route
    onBackButtonPress();
};

and pass handleBackButtonPress to HeaderWithBackButton. That preserves the route while moving forward through the flow, but clears it on a real abandon — satisfying both "clear on entry is stable" and "no stale route."


To be transparent: I verified the data flow and call sites directly from the code (links above), but I did not reproduce the stale-route scenario in a running app — it's plausible and you already agreed it's valid, just flagged here as analysis rather than a confirmed repro.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@samranahm I think we can try to use this approach

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Eskalifer1 We have same approach in AddPersonalBankAccountPage to clear the data on unmount, this make sure we clear everything when flow finish to make sure each new flow start fresh.

useEffect(() => clearPersonalBankAccount, []);

This is already established approach through out the codebase.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's already 1AM for me, so i will take a closer look tomorrow

@samranahm
Copy link
Copy Markdown
Contributor Author

@Eskalifer1 Preserving onSuccessFallbackRoute approach worked, but it indeed leaves an old route saved after the user leaves without finishing. This is most unlikely to happen, but it can still cause a regression, and we should consider it an edge case.

We actually merge onSuccessFallbackRoute in setPersonalBankAccountContinueKYCOnSuccess, which we call before entering the bank account flow (pressing "Add personal bank account" in our case). Then, as soon as we land on AccountFlowEntryPoint after country selection, the whole PERSONAL_BANK_ACCOUNT was wiped to start fresh, which is what removed the route too early.

Here's what I found to be the most professional solution

Wipe PERSONAL_BANK_ACCOUNT on unmount, so we keep the onSuccessFallbackRoute that we save before entering the AccountFlowEntryPoint screen, and clear everything when the user finishes setup or goes back and restarts. This is possible because AccountFlowEntryPoint stays mounted while the user moves forward through the rest of the flow (it's under the same navigation stack), so it only unmounts and clears when the flow closes or the user goes back that is exactly what we wanted here.

@samranahm
Copy link
Copy Markdown
Contributor Author

I also think we should update the preconditions, specifically to specify that both users must have currency in USD: Both users in USD currency default

@Eskalifer1 This one is not needed because we only care about the IOU currency because of the canUseWallet check. The recipient's currency doesn't matter, and instead of changing default currency, the simplest and most reliable way is to select USD on the amount screen during the Pay flow.

I've updated the test step to reflect this and added a new test as well.

@MelvinBot
Copy link
Copy Markdown
Contributor

Short answers

Q2 — How was onSuccessFallbackRoute cleared before this useEffect? It wasn't cleared by the entry‑point effect on purpose — that mount effect (clearPersonalBankAccount()) was just a "start the flow on a clean slate" reset, and wiping the whole PERSONAL_BANK_ACCOUNT object (route included) too early is exactly the bug. The route's real lifecycle is: set before the flow → consumed by continueSetup on success → cleared by the downstream KYC screens, not by the entry point.

Q1 — Can it be fixed with your approach? Yes, but it needs a one‑line signature change to clearPersonalBankAccount so it can re‑seed the route, plus the isLoadingOnyxValue guard you wrote (which is load‑bearing, not optional — see below).


Q2 details: the full lifecycle of onSuccessFallbackRoute
  1. Set before entering the flow via setPersonalBankAccountContinueKYCOnSuccess, which Onyx.merges {onSuccessFallbackRoute} into PERSONAL_BANK_ACCOUNT.
  2. Consumed on the success path: AddBankAccount.exitFlow(true) reads personalBankAccount?.onSuccessFallbackRoute and calls continueSetup. continueSetup only navigates + fires the KYC wall action — it does not clear the route.
  3. Cleared by the downstream KYC continuation screens, which wipe the whole object once we're past the bank‑account step:

So the entry‑point mount clear was redundant for the route's lifecycle — the route is always cleared further down the flow regardless. That's why both the current PR fix and your alternative are safe.


Q1: making your approach work

Two changes are required.

1. Let clearPersonalBankAccount accept a seed (today it's hard‑coded to null at BankAccounts.ts:294-299):

function clearPersonalBankAccount(personalBankAccount?: Partial<PersonalBankAccount>) {
    clearPlaid();
    Onyx.set(ONYXKEYS.PERSONAL_BANK_ACCOUNT, personalBankAccount ?? null);
    Onyx.set(ONYXKEYS.FORMS.PERSONAL_BANK_ACCOUNT_FORM_DRAFT, null);
    clearPersonalBankAccountSetupType();
}

2. In AccountFlowEntryPoint, read the value, derive the route, and guard on the loading state:

const [personalBankAccount, personalBankAccountResult] = useOnyx(ONYXKEYS.PERSONAL_BANK_ACCOUNT);
const isLoadingPersonalBankAccount = isLoadingOnyxValue(personalBankAccountResult);
const onSuccessFallbackRoute = personalBankAccount?.onSuccessFallbackRoute;

useEffect(() => {
    if (isLoadingPersonalBankAccount) {
        return;
    }
    clearPersonalBankAccount(onSuccessFallbackRoute ? {onSuccessFallbackRoute} : undefined);
    // eslint-disable-next-line react-hooks/exhaustive-deps
}, [isLoadingPersonalBankAccount]);

Why the isLoadingOnyxValue guard is essential, not cosmetic: useOnyx returns undefined while the key is still hydrating from storage. If you cleared on the first render before hydration, onSuccessFallbackRoute would be undefined, you'd call clearPersonalBankAccount(undefined)Onyx.set(..., null), and you'd wipe the route again — the exact bug you're fixing. Gating on isLoadingOnyxValue(personalBankAccountResult) defers the clear until the real value is loaded, so you re‑seed the route you actually read. isLoadingOnyxValue lives at src/types/utils/isLoadingOnyxValue (used the same way in DeepLinkHandler.tsx).

One note: keep the dep array as [isLoadingPersonalBankAccount] only (not the route) so the re‑seed write doesn't re‑trigger the effect — hence the exhaustive-deps disable.

Tradeoff vs. the current unmount approach
  • Current PR (useEffect(() => clearPersonalBankAccount, [])): one line, no signature change, and it mirrors the existing pattern already in AddPersonalBankAccountPage.tsx:56. Downside the author already flagged: if the screen is left mounted in an unusual way, stale data could linger.
  • Your approach (preserve route on mount‑clear): keeps the "start fresh on every entry" semantics and surgically preserves only the route, but costs the clearPersonalBankAccount signature change + the hydration guard. Functionally both fix the bug; this one is a bit more defensive about stale in‑progress data, at the cost of slightly more surface area.

@Eskalifer1
Copy link
Copy Markdown
Contributor

@MelvinBot i was asking how we can fix this and how it was working before useEffect with clear was added

@samranahm
Copy link
Copy Markdown
Contributor Author

@Eskalifer1 PR ready for another review, please take a look. Unit test failure is not related to this PR.

@Eskalifer1
Copy link
Copy Markdown
Contributor

Hi @samranahm take a look here pls

@Eskalifer1
Copy link
Copy Markdown
Contributor

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 00b560618b

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

clearPersonalBankAccount();
}, []);
// Clear on unmount so fallback route remains available during the next flow and is clear when the flow ends.
useEffect(() => clearPersonalBankAccount, []);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Clear stale fallback routes before ordinary bank setup

With this cleanup moved entirely to unmount, a stale PERSONAL_BANK_ACCOUNT.onSuccessFallbackRoute can survive into a later non-KYC setup. For example, if a payment/KYC attempt calls setPersonalBankAccountContinueKYCOnSuccess and the user cancels before this entry screen ever unmounts, then later goes through Settings > Wallet > Add bank account > Get reimbursed > United States, this screen no longer clears that old fallback; choosing Plaid/manual only merges setupType, and AddPersonalBankAccountPage.exitFlow(true) will call continueSetup with the stale route after success, triggering the KYC/enable-payments path for a get-reimbursed flow. Preserve the intended fallback for the current KYC flow, but clear stale fallback state when starting an ordinary bank-account flow.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @samranahm Yes, I think that's a valid concern. The problem here is that it also occurs during cleanup on mount.

I think we should revert to the logic I proposed here. That way, we’ll fix the bug and avoid new regressions.

I'm convinced that cleaning up on unmount is a very bad idea and will introduce a lot of new regressions, since the app has been working this way for months—cleaning up data on mount—and changing that now just because of one small bug is a bad idea.

At the very least, I can say that if the user simply closes the page, the cleanup in useEffect won’t run, so the next time the user starts the flow, all their data will be stale, not just onSuccessFallbackRoute—so this is a bad idea, and that’s just one example.

We need to perform cleanup on mount, as is currently the case.

Perhaps we’ll find a solution once we figure out how cleanup worked before this cleanup was added; please check how it worked back then.

Please do not use AI; it’s very noticeable, and AI might give an incorrect result, which will only confuse us further.

We can add a separate cleanup on unmount just for onSuccessFallbackRoute; this way, we’ll preserve the existing logic and fix the bug:

    useEffect(() => {
        if (isLoadingPersonalBankAccount) {
            return;
        }
        clearPersonalBankAccount(onSuccessFallbackRoute ? {onSuccessFallbackRoute} : undefined);
    }, [isLoadingPersonalBankAccount]);

    useEffect(() => () => setPersonalBankAccountContinueKYCOnSuccess(null), []);

Let me know what do you think

@samranahm

This comment was marked as outdated.

@Eskalifer1
Copy link
Copy Markdown
Contributor

@MelvinBot Here's the bug we're dealing with:

Bug: When paying another user with a personal bank account, the KYC flow does not trigger after adding the account.

Root Cause
AccountFlowEntryPoint calls clearPersonalBankAccount() on mount, which sets ONYXKEYS.PERSONAL_BANK_ACCOUNT to null. This wipes onSuccessFallbackRoute — a value written by the pay flow (via setPersonalBankAccountContinueKYCOnSuccess) before navigating to this screen. AddPersonalBankAccountPage and AddBankAccount read onSuccessFallbackRoute after the bank is added to decide where to redirect the user (e.g. into the KYC/enable-payments flow). With it gone, the redirect never happens.

We want to fix this by clearing everything in useEffect except for onSuccessFallbackRoute, but this causes another bug:
onSuccessFallbackRoute is now preserved in Onyx indefinitely(if user doesn't finish flow). If the user abandons the flow mid-way and later opens the add-bank-account flow from an unrelated part of the app (e.g. Wallet settings), AccountFlowEntryPoint mounts again, isLoadingPersonalBankAccount transitions from true → false, and the effect reads the stale onSuccessFallbackRoute from the previous session — preserving it again instead of discarding it. The user ends up being redirected to a route that has nothing to do with their current intent.

Do you have any idea how we can fix that?

Is it good to clear only onSuccessFallbackRoute on unmount? Like this:

useEffect(() => () => setPersonalBankAccountContinueKYCOnSuccess(null), []);

@MelvinBot
Copy link
Copy Markdown
Contributor

Short answer: no. useEffect(() => () => setPersonalBankAccountContinueKYCOnSuccess(null), []) doesn't fix the leak and adds a new gap:

  • It won't run on the case you're worried about. Unmount cleanups don't fire when the app is force-killed — which is exactly your "user abandons mid-way, comes back next session" scenario. The stale onSuccessFallbackRoute still survives into the next session, so the leak is untouched.
  • It only clears one field. The rest of PERSONAL_BANK_ACCOUNT (plaid data, form draft, bankAccountID, shouldShowSuccess, isLoading) is the transient flow state you do want reset — this leaves all of it behind.
  • AccountFlowEntryPoint doesn't unmount when you go forward into AddPersonalBankAccountPage — it stays on the stack underneath. So the cleanup only fires on teardown, which is both too late to help and risky if it races the consumer reading the route.

⚠️ Worth flagging: the PR's current clear-on-unmount has the same latent leak. Kill the app mid-pay-flow → onSuccessFallbackRoute = ENABLE_PAYMENTS persists → next session's unrelated "Get reimbursed" flow reads it on the success screen and wrongly bounces the user into KYC.

Root cause

You're managing the lifecycle of a "continue into KYC" intent from a consuming screen's mount/unmount, but the value lives in persistent Onyx. That mismatch is unwinnable:

  • clear on mount → races the setter that ran right before navigation (your original bug)
  • clear on unmount → never runs on app-kill (your leak)

There's no way to distinguish a freshly-set intent from a stale one by preserving it across a mount, because it's the same persisted key.

Recommended fix — reset at the entry, before the intent is written

Move the reset to the moment a fresh flow begins (race-free, since it runs before navigation), and stop clearing on any screen's mount/unmount.

Option A (minimal). Fold the reset into the setter so writing a fresh intent wipes stale state in the same step:

function setPersonalBankAccountContinueKYCOnSuccess(onSuccessFallbackRoute: Route) {
    clearPersonalBankAccount();                                              // wipes any stale state, incl. a leftover route
    Onyx.merge(ONYXKEYS.PERSONAL_BANK_ACCOUNT, {onSuccessFallbackRoute});    // seeds the fresh intent
}

clearPersonalBankAccount() does Onyx.set(KEY, null), then the merge re-adds just {onSuccessFallbackRoute} — so the result is a clean object with only the fresh route, no race with a later mount effect. Then:

  • Remove the clearPersonalBankAccount from AccountFlowEntryPoint's effect entirely (it's the source of the original race and is now redundant).
  • The continuation entry points (SettlementButton:565, PaymentUtils:262, Search:1335, WalletPage:814) now self-clean on every fresh entry, and the existing clears on the cancel/back/exit paths already reset state when the user bails.
  • For the non-continuation entry (Wallet "Get reimbursed", which never calls the setter), add a clearPersonalBankAccount() before navigating so it can't inherit a stale intent either.

Option B (most robust). Stop storing onSuccessFallbackRoute in Onyx and pass it as a navigation param into the entry point, threaded down to the add-account pages. Params are scoped to the navigation instance — they can't survive into a new session and can't race a clear, which eliminates the whole bug class. Bigger change (threads through CountrySelection → AccountFlowEntryPoint → AddPersonalBankAccountPage/AddBankAccount).

I'd ship A for this PR.

Why A is race-free (full flow trace)

The pay flow sets the intent then navigates, and the destination screen used to clear it on mount:

  1. SettlementButton:565setPersonalBankAccountContinueKYCOnSuccess(ENABLE_PAYMENTS) then triggerKYCFlow navigates in.
  2. Flow screens mount: InternationalDepositAccount → CountrySelection → AccountFlowEntryPoint.
  3. Old code cleared on AccountFlowEntryPoint mount → wiped step 1's intent (original bug).
  4. The fix can't move to mount of any screen, because the setter always runs before that screen mounts — same race. It also can't rely on unmount, which doesn't fire on app-kill (the leak).

Folding the clear into the setter (BankAccounts.ts:292) runs the reset before the intent is written, from the caller, with no dependency on a later mount — so neither the race nor the cross-session leak can occur. The intent is then read once by AddPersonalBankAccountPage exitFlow / AddBankAccount exitFlow and consumed by continueSetup.

All call sites set the intent at the very start of the flow, before any bank-account data exists, so clearing there is always safe.


Next Steps: Reply with @MelvinBot <feedback> to refine, or @MelvinBot implement option A to open a draft PR with the change.

@Eskalifer1
Copy link
Copy Markdown
Contributor

@samranahm Take a look at Option A that Melvin suggested. What do you think of it?

It seems like the best idea is to do the cleanup first and then handle the navigation, but it looks like that would require rewriting quite a bit of code.

@Eskalifer1
Copy link
Copy Markdown
Contributor

@MelvinBot We have two options:

  1. Remove the useEffect with cleanup from AccountFlowEntryPoint and perform the cleanup before the flow begins

  2. Keep the approach I suggested (full cleanup except for onSuccessFallbackRoute), but add the onSuccessFallbackRoute cleanup specifically wherever the flow is initiated.

Which of these two options is better? And which of these options falls within the scope of this PR?

@MelvinBot
Copy link
Copy Markdown
Contributor

Option 1 is better, and the initiation-time cleanup it relies on is required in this PR either way.

Why Option 1 wins: both options add the same "clear when the flow is initiated" step — the difference is that Option 2 also keeps a partial "clear everything except onSuccessFallbackRoute" on mount. That splits the reset across two places (non-route fields cleared on mount, route cleared at initiation) that must stay in sync, and keeps the fragile mount/isLoading timing dependency that caused your stale-read in the first place. Option 1 does the whole reset in one place (the entry), with a single source of truth and no mount-timing coupling. Same correctness, less surface area.

On scope — this is the key point: the cleanup-at-initiation is not optional follow-up; it's needed to avoid a regression this PR introduces.

  • On main, AccountFlowEntryPoint's mount-clear scrubs stale PERSONAL_BANK_ACCOUNT state on every fresh entry (that's exactly why it also wiped the freshly-set intent — your original bug).
  • Moving it to unmount removes that scrub, so a stale onSuccessFallbackRoute left by a force-killed session now survives into the next, unrelated flow → the exitFlow consumers read it and wrongly bounce the user into KYC (breaking the premise of your own Test 02).

So whichever option you pick, you have to add the initiation-time reset to not regress. Option 1 is just the minimal, clean way to do it — keep it in this PR.

Concrete shape of Option 1
  1. Remove useEffect(() => clearPersonalBankAccount, []) from AccountFlowEntryPoint.tsx:44.
  2. Fold the reset into the setter so every continuation entry self-cleans, race-free — covers SettlementButton:565, PaymentUtils:262, Search:1335, WalletPage:814 in one place:
    // BankAccounts.ts:292
    function setPersonalBankAccountContinueKYCOnSuccess(onSuccessFallbackRoute: Route) {
        clearPersonalBankAccount();
        Onyx.merge(ONYXKEYS.PERSONAL_BANK_ACCOUNT, {onSuccessFallbackRoute});
    }
  3. The non-continuation entry (Wallet "Get reimbursed", which never calls the setter) needs its own clearPersonalBankAccount() before navigating in, since it no longer inherits the mount-scrub — otherwise it can read a stale intent.
  4. The existing clears on the cancel/back/exit paths stay as-is.

Note: Option 2 needs steps 1's-equivalent + 3 too, plus the partial mount-clear — so it's strictly more code for the same result.


Next Steps: Reply with @MelvinBot implement option 1 to open a draft PR with this change, or @MelvinBot <feedback> to refine.

@Eskalifer1
Copy link
Copy Markdown
Contributor

@MelvinBot I understand that we need to add this cleanup everywhere the flow can start. Could you help identify all of those entry points?

From my understanding, the cleanup should be added not only in places where we set onSuccessFallbackRoute, but also in flows where it isn't set. Otherwise, if a user exits midway through a flow that has onSuccessFallbackRoute and then starts another flow that doesn't, the stale value could remain and the cleanup logic might not work correctly.

Link all places where we need to add this cleanup. Maybe we can do something so we don't have to repeat the same thing in every place where logic related to AccountFlowEntryPoint is used, but instead do it just once somewhere?

@MelvinBot
Copy link
Copy Markdown
Contributor

Mapped every entry point. Short answer: the non‑setter flows really do funnel through a single function (openPersonalBankAccountSetupView), so that's the natural "do it once" spot — but a blanket clear there is not safe, because two of the setter flows write onSuccessFallbackRoute either just before or just after that function runs and a clear would wipe the value they just set. So there are two clean designs that genuinely remove the cleanup obligation from every entry point; I'd lean toward moving the route off Onyx onto a navigation param (details below).

The two live consumers

onSuccessFallbackRoute is only ever read in two places (this is where "continue KYC after adding a bank account" actually fires):

Consumer Mounted as
AddPersonalBankAccountPage.tsx#L42-L56 IOU_SEND.ADD_BANK_ACCOUNT, SETTINGS.ADD_US_BANK_ACCOUNT, ADD_PERSONAL_BANK_ACCOUNT_ROOT
EnablePayments/.../AddBankAccount.tsx#L53-L66 rendered by EnablePayments.tsx#L76 at SETTINGS.WALLET.ENABLE_PAYMENTS

All entry points that start the personal‑bank‑account flow

A. Sites that SET the route (4):

Site Route set How
SettlementButton/index.tsx#L557-L566 ENABLE_PAYMENTS after triggerKYCFlow
PaymentUtils.ts#L257-L264 ENABLE_PAYMENTS after triggerKYCFlow
actions/Search.ts#L1325-L1337 ENABLE_PAYMENTS after triggerKYCFlow
WalletPage/index.tsx#L806-L815 SETTINGS_WALLET inside KYCWall's onSelectPaymentMethod callback

B. Non‑setter flows — all go through openPersonalBankAccountSetupView (5):

C. Outliers that raw‑navigate into the flow and bypass the opener entirely (these are why per‑entry‑point clears are fragile):

Why "clear once in openPersonalBankAccountSetupView" doesn't work

It looks like the perfect chokepoint, but the setter flows interleave with it badly:

The two ordering traps (verified)

selectPaymentMethod in BaseKYCWall does this in one synchronous block:

// BaseKYCWall.tsx
if (paymentMethod) { onSelectPaymentMethod(paymentMethod); }   // L135  ← WalletPage sets the route HERE
if (paymentMethod === PERSONAL_BANK_ACCOUNT) {
    openPersonalBankAccountSetupView({...});                   // L139  ← a clear here would wipe it in the same tick
}
  1. WalletPage sets the route via onSelectPaymentMethod (L135), which runs immediately before the opener (L139). A clear at the top of the opener wipes it synchronously.
  2. SettlementButton / PaymentUtils / Search set the route after triggerKYCFlow returns. In the popover branch (BaseKYCWall.tsx#L312-L313) the opener only runs later, when the user taps the menu item — i.e. after the setter already wrote. A clear in the opener wipes it then.

So a single clear in the opener correctly resets the 5 non‑setter flows but corrupts the 4 setter flows.

Recommendation

Option 1 — move the route off Onyx onto a navigation param (recommended).
Pass the continue‑route as a route param to the two consumer screens instead of storing it on the persisted PERSONAL_BANK_ACCOUNT Onyx key. A nav param is created by the navigate call and lives only on that route instance, which fixes all three problems at once:

  • Non‑setter flows simply never attach it → no stale value, no clear needed in any entry point.
  • It can't survive an app force‑kill → the "preserved in Onyx indefinitely" bug you raised earlier disappears by construction.
  • It travels atomically with the navigate → none of the ordering traps above.

Shape: the consumers read route.params.onSuccessFallbackRoute; the 4 setter sites pass it as a param when navigating; delete setPersonalBankAccountContinueKYCOnSuccess and the onSuccessFallbackRoute field on the Onyx type. The clear‑on‑unmount tweak in this PR then becomes unnecessary.

Option 2 — if you want to stay on Onyx: make the opener the single writer.
Give openPersonalBankAccountSetupView an onSuccessFallbackRoute arg (default null) and have it Onyx.merge(... {onSuccessFallbackRoute}) — i.e. set when provided, clear (null) when not. Non‑setter callers pass nothing → stale value cleared; setter callers pass the route → the 4 separate setPersonalBankAccountContinueKYCOnSuccess calls go away. To make this correct you'd thread the route through continueAction/selectPaymentMethod so the KYC‑wall setters pass it into the opener rather than writing around it. Residual cost: the Section‑C outliers and deep links don't pass through the opener, so each still needs handling — which is exactly why Option 1 is cleaner.

Either way, the answer to "do it just once somewhere" is yes — but the single place should be the route's writer (the opener, or better, the navigation action), not a clear sprinkled at each entry. A clear in the opener alone is unsafe for the reasons above.

Heads‑up unrelated to the above: the clear‑on‑unmount in this PR (AccountFlowEntryPoint.tsx#L44) doesn't run on a hard app kill, so a force‑killed app mid‑flow still leaves onSuccessFallbackRoute behind. Option 1 removes that failure mode too.


Next Steps: Reply with @MelvinBot <feedback> to refine this, or @MelvinBot implement option 1 to draft the nav‑param change.

@Eskalifer1
Copy link
Copy Markdown
Contributor

@samranahm Please take a look at the solutions Melvin has suggested to see which one works best. Do you perhaps have another solution that would work better?

@samranahm
Copy link
Copy Markdown
Contributor Author

Looking into it, I'll explore each one and will let you know about my findings regarding these.

@Eskalifer1
Copy link
Copy Markdown
Contributor

@samranahm Thank you! I'll be OOO part of the day tomorrow and all next week, so I'll review everything once I'm back. If you have any higher-priority tasks, feel free to work on them now!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants