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-11-10] [$175] Bank account-This field is required error in the company name field after completing Onfido #104049
Version Number: 9.5.9-0 Reproducible in staging?: Yes Reproducible in production?: Unable to validate in Prod - Provide reasoning. If this was caught during regression testing, add the test name, ID and link from BrowserStack:https://test-management.browserstack.com/tc/TC-3413 Email or phone of affected tester (no customers): N/A Issue reported by: Applause Internal Team Bug source: Exploratory - Significant User Experience Deterioration Device used: iPhone 15 iOS 26.6.1 App Component: Other
Action Performed:
Sign in to ND
Create a workspace, go to Workflows/ Payments
Tap Add bank account - Log into your bank - Regions bank - Saving account 1111
Set the First Name: First, Last Name: Last
Complete the personal details step
Tap Continue and complete the Onfido verification process, tap Submit video
Observe the company name field after being navigated to the Company info step
Expected Result:
No errors appear on the Company info page
Actual Result:
"This field is required" error is shown in the company name field after completing Onfido verification flow
The Company name input loses focus without any user action, and that blur triggers the form's "required" check while the field is still empty.
After Onfido succeeds, handleOnfidoSuccess navigates to the Company step right away (VerifyIdentity.tsx:53-60). On iOS, the full-screen native Onfido screen is still closing at that moment.
The Company name step uses shouldDelayAutoFocus (NameBusiness.tsx:70). That calls focus() after a fixed 300 ms timer (useDelayedAutoFocus.ts:20-22). The timer does not wait for the transition or the native screen to finish closing.
iOS then removes focus from the input, so onBlur fires. On native, Visibility.hasFocus() always returns true (Visibility/index.native.ts:9). Nothing filters out this blur, so FormProvider marks the field as touched and validates it (FormProvider.tsx:505-534).
getFieldRequiredErrors returns "This field is required" for the empty companyName (NameBusiness.tsx:38).
What changes do you think we should make in order to solve the problem?
Make useDelayedAutoFocus focus the input only after the transition really ends, not on a fixed timer. Use TransitionTracker.runAfterTransitions (with waitForUpcomingTransition), then isWindowReadyToFocus(). This is the pattern useAutoFocusInput already uses (useAutoFocusInput.ts:72-77). Cancel the task handle when the screen loses focus.
This fixes the bug for every SingleFieldStep that uses shouldDelayAutoFocus, not just this one.
What alternative solutions did you explore? (Optional)
Delay onSubmit() in handleOnfidoSuccess until the native Onfido screen has closed. This is narrower, and it only fixes the Onfido path.
Skip blur validation in FormProvider for fields the user has never pressed or edited. This changes how every form behaves, so it carries more regression risk.
Investigation details
The error comes from the client's own validation, not the server. verifyIdentityForBankAccount only updates REIMBURSEMENT_ACCOUNT (isLoading and errors). It never sets errorFields on the form.
A new FormProvider starts with no fields touched. So the error needs a blur or a submit on the Company form itself. That rules out stale state carried over from the Onfido step.
This is likely iOS-only. iOS shows Onfido as a full-screen native view controller, and closing it can remove focus from an input that gained focus while it was closing.
I found no single PR that caused this. The relevant files have had no logic changes in about 2 months.
I checked this in the code only. I did not reproduce it on an iOS device.
Next Steps for Contributor+ team: To accept:@MelvinBot implement [this](https://github.com/Expensify/App/issues/104049) to create a draft PR. To refine:@MelvinBot <your feedback> To reject: Explain why you are rejecting Melvin's proposal.
changed the title [-]Bank account-This field is required error in the company name field after completing Onfido[/-][+][$175] Bank account-This field is required error in the company name field after completing Onfido[/+]on Oct 14, 2026
Please re-state the problem that we are trying to solve in this issue.
After completing the Onfido verification step, the user is navigated to the Company Info screen, where the "Company name" field immediately shows a "This field is required" error before the user has interacted with it.
What is the root cause of that problem?
This is a state-leak issue, not a mount-time validation bug. The shared form wrapper is rehydrating stale field errors from the previous reimbursement-account step.
When VerifyIdentity.tsx completes the Onfido flow, it updates the draft state and advances the user, but it fails to clear the shared ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM error state in Onyx.
BusinessInfo.tsx mounts the next sub-step (NameBusiness.tsx).
Inside FormProvider.tsx, the component reads formState.errorFields during input registration. Because the Onyx state was never wiped during the transition, the companyName field consumes the stale required-field error and renders it immediately on first paint.
The validate callback in NameBusiness.tsx is correctly configured to fire only on change/blur/submit, meaning the error is strictly a residual Onyx artifact.
What changes do you think we should make in order to solve the problem?
We need to explicitly clear the shared form errors when transitioning out of the Onfido step so the Business Info step mounts with a clean validation slate.
In src/pages/ReimbursementAccount/USD/Requestor/VerifyIdentity/VerifyIdentity.tsx, right before or immediately after we call updateReimbursementAccountDraft({isOnfidoSetupComplete: true}); and trigger the step advancement, we should dispatch a clear action to Onyx:
JavaScript
import * as FormActions from '@libs/actions/FormActions';
import ONYXKEYS from '@src/ONYXKEYS';
// Inside the Onfido success callback / onSubmit:
FormActions.clearErrors(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM);
FormActions.clearErrorFields(ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM);
Alternatively, if we want a more resilient screen-level guard, we can add a mount useEffect in BusinessInfo.tsx that calls FormActions.clearErrorFields(...) on initial load. However, wiping it on the success transition in VerifyIdentity is cleaner.
What alternative solutions did you explore? (Optional)
A UI-only fix: adding a hasInteracted state flag locally inside NameBusiness.tsx to suppress errors until the user types. I rejected this because it masks the corrupted ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM state. The shared form state must be explicitly cleared to prevent this error from leaking into other sub-steps or blocking future submissions.
Please re-state the problem that we are trying to solve in this issue.
In the USD Verified Bank Account setup flow, after completing the Onfido identity verification step and submitting the video, the user is automatically navigated to the Company Info step (NameBusiness / Enter Business Name). Upon arriving at the screen without any user interaction or typing, the company name input immediately displays a red error: "This field is required".
What is the root cause of that problem?
The root cause is a race condition between native modal dismissal/navigation transition on iOS and the fixed setTimeout in useDelayedAutoFocus:
When Onfido verification succeeds on native iOS, VerifyIdentity.tsx:53-60 immediately triggers onSubmit(). At this moment, the native Onfido SDK (@onfido/react-native-sdk) full-screen modal UIViewController is still animating closed.
USDVerifiedBankAccountFlowPage navigates to NameBusiness, which renders SingleFieldStep.tsx with shouldDelayAutoFocus={true}.
SingleFieldStep delegates autofocus to useDelayedAutoFocus.ts:20-22. Currently, useDelayedAutoFocus uses a blind, fixed timer:
Because the iOS native modal dismissal and navigation transition typically take ~350–500 ms, ref.current?.focus() fires prematurely while the native view hierarchy is still resolving.
As the native modal finish-dismisses, iOS resets the first responder hierarchy, causing an involuntary onBlur event on the TextInput.
On native platforms, Visibility.hasFocus() unconditionally returns true. Therefore, in FormProvider.tsx:502-532, FormProvider treats this involuntary dismissal blur as a user-initiated blur:
setTouchedInput(inputID) marks companyName as touched.
Because companyName is still empty, getFieldRequiredErrors assigns errors.companyName = "This field is required".
The user arrives on the screen and is immediately confronted with "This field is required".
What changes do you think we should make in order to solve the problem?
Refactor useDelayedAutoFocus in useDelayedAutoFocus.ts so that instead of using an arbitrary 300 ms timer, it waits for transitions to actually complete using navigation.addListener('transitionEnd'), TransitionTracker.runAfterTransitions, and isWindowReadyToFocus(), following the established autofocus architecture in useAutoFocusInput.ts.
Targeted Implementation in src/hooks/useDelayedAutoFocus.ts:
No premature focus: Focus is deferred until the screen transition and any overlapping native modal dismissals have fully settled.
No involuntary blur: Because focus is only applied once the view hierarchy is stable, iOS does not resign the first responder immediately after focus.
No premature validation: Without an involuntary blur, FormProvider's onBlur does not fire, keeping the field untouched until the user actually interacts or submits.
App-wide coverage: Fixes all substeps across USD and Non-USD bank account verification flows that rely on SingleFieldStep and RegistrationNumberStep with shouldDelayAutoFocus.
What alternative solutions did you explore? (Optional)
Delaying onSubmit in VerifyIdentity.tsx: We could delay navigation in handleOnfidoSuccess until after the Onfido modal dismisses. However, this only patches the Onfido transition and does not protect against general navigation transition race conditions on slower devices.
Preventing blur validation on untouched fields in FormProvider.tsx: We considered modifying FormProvider's onBlur handler to ignore blurs if the user never entered keystrokes. However, this alters form validation behavior globally across the entire app and carries high regression risk compared to fixing the autofocus timing hook.
Unit / Regression Tests
Unit test: Add unit tests in tests/unit/useDelayedAutoFocusTest.ts to verify that useDelayedAutoFocus:
Does not trigger focus when shouldDelayAutoFocus is false.
Waits for transitionEnd event before invoking ref.current.focus().
Correctly cleans up transitionEnd listener and cancels TransitionTracker handle on screen blur / unmount.
Respects tryClaim(Priorities.AUTO) and shouldSkipAutoFocusDueToExistingFocus().
Manual QA Steps:
Sign in to NewDot on an iOS device.
Create a workspace and navigate to Workflows > Payments.
Tap Add bank account > Connect bank > select any bank and account.
Fill in Personal Details (First Name, Last Name, SSN, Address, etc.) and tap Continue.
Complete Onfido verification and tap Submit video.
Verify that upon landing on the "Enter the name of your business" step, the company name input is focused cleanly and NO red error "This field is required" is displayed.
Clear the field (or leave empty) and tap Next.
Verify that on explicit submission, "This field is required" validation still correctly triggers.
Activity
applause-bot commentedon Oct 14, 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/89557d08b0f0aff5880c5e7ae3bb4d7811bd369d95d0694f30d77edab0dfda3b
MelvinBot commentedon Oct 14, 2026
Proposal
What is the root cause of that problem?
The Company name input loses focus without any user action, and that blur triggers the form's "required" check while the field is still empty.
handleOnfidoSuccessnavigates to the Company step right away (VerifyIdentity.tsx:53-60). On iOS, the full-screen native Onfido screen is still closing at that moment.shouldDelayAutoFocus(NameBusiness.tsx:70). That callsfocus()after a fixed 300 ms timer (useDelayedAutoFocus.ts:20-22). The timer does not wait for the transition or the native screen to finish closing.onBlurfires. On native,Visibility.hasFocus()always returnstrue(Visibility/index.native.ts:9). Nothing filters out this blur, soFormProvidermarks the field as touched and validates it (FormProvider.tsx:505-534).getFieldRequiredErrorsreturns "This field is required" for the emptycompanyName(NameBusiness.tsx:38).What changes do you think we should make in order to solve the problem?
Make
useDelayedAutoFocusfocus the input only after the transition really ends, not on a fixed timer. UseTransitionTracker.runAfterTransitions(withwaitForUpcomingTransition), thenisWindowReadyToFocus(). This is the patternuseAutoFocusInputalready uses (useAutoFocusInput.ts:72-77). Cancel the task handle when the screen loses focus.This fixes the bug for every
SingleFieldStepthat usesshouldDelayAutoFocus, not just this one.What alternative solutions did you explore? (Optional)
onSubmit()inhandleOnfidoSuccessuntil the native Onfido screen has closed. This is narrower, and it only fixes the Onfido path.FormProviderfor fields the user has never pressed or edited. This changes how every form behaves, so it carries more regression risk.Investigation details
verifyIdentityForBankAccountonly updatesREIMBURSEMENT_ACCOUNT(isLoadinganderrors). It never setserrorFieldson the form.FormProviderstarts with no fields touched. So the error needs a blur or a submit on the Company form itself. That rules out stale state carried over from the Onfido step.shouldDelayAutoFocus. A fixed 300 ms delay is not enough when a native modal is closing at the same time.Next Steps for Contributor+ team:
To accept:
@MelvinBot implement [this](https://github.com/Expensify/App/issues/104049)to create a draft PR.To refine:
@MelvinBot <your feedback>To reject: Explain why you are rejecting Melvin's proposal.
view run
melvin-bot commentedon Oct 14, 2026
Triggered auto assignment to Contributor-plus team member for initial proposal review - @Eskalifer1 (
External)[-]Bank account-This field is required error in the company name field after completing Onfido[/-][+][$175] Bank account-This field is required error in the company name field after completing Onfido[/+]melvin-bot commentedon Oct 14, 2026
Job added to Upwork: https://www.upwork.com/jobs/~022110486592159765703
juni2003 commentedon Oct 14, 2026
Contributor details
Your Expensify account email: juni.xatti@gmail.com
Upwork Profile Link: https://www.upwork.com/freelancers/~01867ae3203c9b7815?mp_source=share
Proposal
Please re-state the problem that we are trying to solve in this issue.
After completing the Onfido verification step, the user is navigated to the Company Info screen, where the "Company name" field immediately shows a "This field is required" error before the user has interacted with it.
What is the root cause of that problem?
This is a state-leak issue, not a mount-time validation bug. The shared form wrapper is rehydrating stale field errors from the previous reimbursement-account step.
VerifyIdentity.tsxcompletes the Onfido flow, it updates the draft state and advances the user, but it fails to clear the sharedONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORMerror state in Onyx.BusinessInfo.tsxmounts the next sub-step (NameBusiness.tsx).FormProvider.tsx, the component readsformState.errorFieldsduring input registration. Because the Onyx state was never wiped during the transition, thecompanyNamefield consumes the stale required-field error and renders it immediately on first paint.The
validatecallback inNameBusiness.tsxis correctly configured to fire only on change/blur/submit, meaning the error is strictly a residual Onyx artifact.What changes do you think we should make in order to solve the problem?
We need to explicitly clear the shared form errors when transitioning out of the Onfido step so the Business Info step mounts with a clean validation slate.
In
src/pages/ReimbursementAccount/USD/Requestor/VerifyIdentity/VerifyIdentity.tsx, right before or immediately after we callupdateReimbursementAccountDraft({isOnfidoSetupComplete: true});and trigger the step advancement, we should dispatch a clear action to Onyx:JavaScript
Alternatively, if we want a more resilient screen-level guard, we can add a mount
useEffectinBusinessInfo.tsxthat callsFormActions.clearErrorFields(...)on initial load. However, wiping it on the success transition inVerifyIdentityis cleaner.What alternative solutions did you explore? (Optional)
A UI-only fix: adding a
hasInteractedstate flag locally insideNameBusiness.tsxto suppress errors until the user types. I rejected this because it masks the corruptedONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORMstate. The shared form state must be explicitly cleared to prevent this error from leaking into other sub-steps or blocking future submissions.melvin-bot commentedon Oct 14, 2026
✅ Contributor details stored successfully. Thank you for contributing to Expensify!
melvin-bot commentedon Oct 14, 2026
✅ Contributor details stored successfully. Thank you for contributing to Expensify!
janiya2 commentedon Oct 14, 2026
Contributor details
Your Expensify account email: janithad2@gmail.com
Upwork Profile Link: https://www.upwork.com/freelancers/janithad
Proposal
Please re-state the problem that we are trying to solve in this issue.
In the USD Verified Bank Account setup flow, after completing the Onfido identity verification step and submitting the video, the user is automatically navigated to the Company Info step (
NameBusiness/ Enter Business Name). Upon arriving at the screen without any user interaction or typing, the company name input immediately displays a red error:"This field is required".What is the root cause of that problem?
The root cause is a race condition between native modal dismissal/navigation transition on iOS and the fixed
setTimeoutinuseDelayedAutoFocus:VerifyIdentity.tsx:53-60immediately triggersonSubmit(). At this moment, the native Onfido SDK (@onfido/react-native-sdk) full-screen modalUIViewControlleris still animating closed.USDVerifiedBankAccountFlowPagenavigates toNameBusiness, which rendersSingleFieldStep.tsxwithshouldDelayAutoFocus={true}.SingleFieldStepdelegates autofocus touseDelayedAutoFocus.ts:20-22. Currently,useDelayedAutoFocususes a blind, fixed timer:CONST.ANIMATED_TRANSITIONis 300 ms.ref.current?.focus()fires prematurely while the native view hierarchy is still resolving.onBlurevent on theTextInput.Visibility.hasFocus()unconditionally returnstrue. Therefore, inFormProvider.tsx:502-532,FormProvidertreats this involuntary dismissal blur as a user-initiated blur:setTouchedInput(inputID)markscompanyNameas touched.onValidate(latestValues)runsvalidate()fromNameBusiness.tsx:38.companyNameis still empty,getFieldRequiredErrorsassignserrors.companyName = "This field is required"."This field is required".What changes do you think we should make in order to solve the problem?
Refactor
useDelayedAutoFocusinuseDelayedAutoFocus.tsso that instead of using an arbitrary 300 ms timer, it waits for transitions to actually complete usingnavigation.addListener('transitionEnd'),TransitionTracker.runAfterTransitions, andisWindowReadyToFocus(), following the established autofocus architecture inuseAutoFocusInput.ts.Targeted Implementation in
src/hooks/useDelayedAutoFocus.ts:Why this completely resolves the issue:
FormProvider'sonBlurdoes not fire, keeping the field untouched until the user actually interacts or submits.SingleFieldStepandRegistrationNumberStepwithshouldDelayAutoFocus.What alternative solutions did you explore? (Optional)
onSubmitinVerifyIdentity.tsx: We could delay navigation inhandleOnfidoSuccessuntil after the Onfido modal dismisses. However, this only patches the Onfido transition and does not protect against general navigation transition race conditions on slower devices.FormProvider.tsx: We considered modifyingFormProvider'sonBlurhandler to ignore blurs if the user never entered keystrokes. However, this alters form validation behavior globally across the entire app and carries high regression risk compared to fixing the autofocus timing hook.Unit / Regression Tests
Unit test: Add unit tests in
tests/unit/useDelayedAutoFocusTest.tsto verify thatuseDelayedAutoFocus:shouldDelayAutoFocusisfalse.transitionEndevent before invokingref.current.focus().transitionEndlistener and cancelsTransitionTrackerhandle on screen blur / unmount.tryClaim(Priorities.AUTO)andshouldSkipAutoFocusDueToExistingFocus().Manual QA Steps:
Workflows>Payments."This field is required"is displayed."This field is required"validation still correctly triggers.melvin-bot commentedon Oct 14, 2026
✅ Contributor details stored successfully. Thank you for contributing to Expensify!
39 remaining items
melvin-bot commentedon Nov 9, 2026
Triggered auto assignment to @mallenexpensify (
Awaiting Payment)melvin-bot commentedon Nov 9, 2026
Payment Summary
Resolving PRs:
Replace useDelayedAutoFocus with useAutoFocusInput in sub-step forms #105572
Reviewer: @mkhutornyi owed $175 via NewDot
BugZero Checklist (@mallenexpensify)
melvin-bot commentedon Nov 12, 2026
@mallenexpensify Whoops! This issue is 2 days overdue. Let's get this updated quick!
mallenexpensify commentedon Nov 13, 2026
Payment Summary
Contributor+: @mkhutornyi due $175 via NewDot