Skip to content

Non-USD (UK) bank account signer/director verification stuck: signerEmail submitted blank (esp. in Copilot sessions) #97151

Description

@melvin-bot

Problem

When adding a non-USD (e.g. UK/GB) business bank account, the signer/director verification step can get permanently stuck on the "hang tight" screen with no way to go back or restart. Under the hood the SaveCorpayOnboardingDirectorInformation request is submitted with a blank signerEmail, which fails a required-field check, so the flow never progresses.

This is a frontend bug: the director form does not carry forward the signer email that was already entered/stored earlier in the flow. Instead it re-derives signerEmail from the currently logged-in user's account.primaryLogin. When that value is empty (or belongs to the wrong account), a blank signerEmail is shipped.

Copilot/delegate trigger

This is especially reproducible in a Copilot (delegated access) session. When a delegate is acting on another user's account, account.primaryLogin reflects the delegate's state (and can also go stale/blank right after a delegate switch), so the value fed into signerEmail is wrong for the account being acted on. It can also occur in a normal session whenever account.primaryLogin is unhydrated at submit time (e.g. after a remove/re-add of the bank account).

Affected flows

The bug lives in the shared non-USD Corpay onboarding code, so it affects both:

  • Global Reimbursement (Workflows/Payments → connect manually → non-USD setup)
  • Expensify Card UK/EU enrollment

Both entry points converge on the same NonUSD setup wizard and the same signer components, so QA should cover both.

Root cause (frontend)

signerEmail is derived from account?.primaryLogin ?? '' in both signer/director submission paths:

There is no fallback if that value is empty, so a blank signerEmail is submitted and rejected by the backend's required-field validation. (The backend relays the frontend value verbatim and has no server-side fallback either — the email the user entered is already stored earlier in the flow, it's just not reused here.)

Suggested fix

Source signerEmail from the account being acted on / the value already captured earlier in the flow (e.g. the stored reimbursementAccount.achData.corpay.signerEmail or session.email) rather than account.primaryLogin — at minimum whenever a Copilot/delegate session is active. Apply the same change to both submission paths above.

QA

  • Complete UK/non-USD bank account signer/director verification in a normal session → succeeds.
  • Complete it in a Copilot/delegate session → succeeds (previously stuck on "hang tight").
  • Verify via both the Global Reimbursement and Expensify Card UK/EU entry points.

Reported from an internal investigation in Expensify/Expensify#664293.

Issue OwnerCurrent Issue Owner: @situchan

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions