Skip to content

Company cards - Broken card feed connection RHP spins forever with no error when the feed has a feed-level error #100465

Description

@MelvinBot

Action Performed:

  1. Set up a workspace with a direct (Plaid) company card feed.
  2. Get the feed into a state where the feed itself has an error recorded (a backend card-import call for the feed fails), but no individual card has a broken scrape result. This makes hasFeedErrors true while isFeedConnectionBroken is false.
  3. Go to Workspace → Company Cards. The banner "Card feed connection is broken. Please log into your bank so we can establish the connection again." is shown, and card assignment is blocked.
  4. Click log into your bank (or attempt to assign a card on that feed).
  5. Complete the bank login in the Plaid window.

Expected Result:

The reconnect flow either completes and closes the RHP, or shows an actionable error explaining that the reconnect failed.

Actual Result:

The RHP shows a back chevron, the title "Assign card", and a spinner — forever. There is no error, no timeout, and no way forward. The only option is to back out and retry, which lands in the same place.

Root Cause:

Two different definitions of "broken connection" disagree, and the page has no error state to fall back on.

  1. The entry gate is broad. useAssignCard.ts:74 sets isSelectedFeedConnectionBroken = shouldPromptBrokenConnection || hasFeedErrors, and routes to the broken-connection page at useAssignCard.ts:119. A feed-level error sets hasFeedErrors, so we enter BrokenCardFeedConnectionPage. The banner uses the same disjunction at getShouldShowBrokenConnectionError.ts:14.

  2. The inner branch is narrow. useUpdateFeedBrokenConnection.ts:22 derives isFeedConnectionBroken from card-level scrape failures only — it is false in this state. So BankConnection/index.tsx:126-139 skips the updateBrokenConnection() + closeRHPFlow() branch and instead takes the healthy-feed path, setting currentStep to ASSIGNEE or CONFIRMATION.

  3. The host page cannot render that step. BrokenCardFeedConnectionPage.tsx:43-62 handles only BANK_CONNECTION and PLAID_CONNECTION. Every other step falls through to default: <LoadingPage title={translate('workspace.companyCards.assignCard')} /> — which is exactly the "Assign card" + spinner screen users report.

The same dead end was already fixed on the sibling page. RefreshCardFeedConnectionPage got both an isRefreshing guard in BankConnection (see the comment at BankConnection/index.tsx:132-133: "RefreshCardFeedConnectionPage can't render it and the modal would spin forever") and a NotFoundPage guard at RefreshCardFeedConnectionPage.tsx:70-72. BrokenCardFeedConnectionPage was left unguarded and still has neither.

Second path to the same spinner. If the feed's expiration is stale, BankConnection/index.tsx:141-143 returns early and waits for expiration to advance — which requires the card-import call to succeed, which is the thing that is failing. That renders the bare ActivityIndicator at BankConnection/index.tsx:219-224, also under an "Assign card" header. Both paths are closed by the same change.

Nothing surfaces the underlying failure either. useImportPlaidAccounts.ts:21-26 silently no-ops on an empty account list, and Plaid.ts:64-101 has no successData and no client-side timeout on plaidData.isLoading.

Proposed Direction:

  1. Give BrokenCardFeedConnectionPage the same NotFoundPage guard its sibling has, so an unrenderable step is never silently swallowed by a spinner.
  2. Stop BankConnection from setting a currentStep the host page cannot render when it was entered from the broken-connection route — mirror the existing isRefreshing guard.
  3. Surface an error state when the card-import call fails, instead of leaving plaidData.isLoading set indefinitely.

Platforms:

  • Windows: Chrome
  • MacOS: Chrome / Safari

Notes:

  • Production logs confirm the server side of the reconnect returns jsonCode 200 and a valid Plaid link token; the client then makes no further API calls and simply spins. The stall is entirely client-side.
  • The trigger in the observed cases is a backend card-import failure that writes a feed-level error. That backend bug is tracked separately and is being worked on internally — this issue is only about the App never showing an error and spinning forever, which is a bug regardless of what caused the underlying failure.
  • Related: Company cards - Add cards RHP spins forever when adding a second Amex card under the same login (OAuth direct feed) #97924 — same "RHP spins forever with no error" shape in the company-cards flow, different code path (OAuth feed-key detection). Worth fixing together.

Filed from an internal support escalation; full log evidence lives in the linked internal issue.

Issue OwnerCurrent Issue Owner: @jmusial

Activity

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

Metadata

Metadata

Labels

BugSomething is broken. Auto assigns a BugZero manager.ReviewingHas a PR in reviewTaskWeeklyKSv2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions