Skip to content

Expensify Card list hides a cardholder's card when their employeeList entry has errors #100723

Description

@MelvinBot

Problem

On Workspace > Expensify Card, a cardholder's card silently disappears from the list if that member's employeeList entry carries an errors object — even though the member is still listed on Workspace > Members and the server returns the card normally.

The two pages call the same helper with different flags, so they disagree about who is a member:

Page Call Errored members
Workspace > Members WorkspaceMembersPage.tsx:113(policy?.employeeList, true) shown
Workspace > Expensify Card WorkspaceExpensifyCardListPage.tsx:111(policy?.employeeList) dropped

includeMemberWithErrors defaults to false (PolicyUtils.ts:841), and the errored member is skipped entirely at PolicyUtils.ts:845-850 — so their accountID never reaches the array. getCardsByCardholderName, CardUtils.ts:636-645 then drops every card whose accountID isn't in it:

if (!card.accountID || !policyMembersAccountIDs.includes(card.accountID)) {
    return;
}

The flag exists for a UI reason — the docblock says it's so "the members with errors would immediately be removed before the user has a chance to read the error." That rationale doesn't transfer to a card list, where it just hides real cards.

Action Performed

  1. Open a workspace with the Expensify Card feed enabled and at least one member holding an Expensify Card.
  2. Put that member's employeeList entry into an error state — for example, trigger a member update or role change that fails and leaves a red-brick-road errors object on the entry.
  3. Go to Workspace > Members.
  4. Go to Workspace > Expensify Card.

Expected Result

The member's Expensify Card is listed on Workspace > Expensify Card, as it was before the error.

Actual Result

The member is listed on Workspace > Members (with an error indicator), but their card is missing from Workspace > Expensify Card. Nothing explains the absence — the card looks deleted. An admin trying to manage that card (raise a limit, unsuspend, replace it) has no way to reach it from NewDot.

Proposed Fix

Pass includeMemberWithErrors = true at WorkspaceExpensifyCardListPage.tsx:111:

const policyMembersAccountIDs = Object.values(getMemberAccountIDsForWorkspace(policy?.employeeList, true));

A card's visibility to an admin should not depend on a transient error object on the member record. Worth auditing the other flag-less call sites for the same class of problem — grep -rn "getMemberAccountIDsForWorkspace(" src/ shows several that pass no flags.

Related

#47729 — same root pattern (a member with an error became hidden), fixed for the approver page in 2024. The Expensify Card list never got the equivalent treatment.

Found while investigating an internal support escalation where an admin's card had gone missing from the workspace card list while the cardholder was still a listed workspace member.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugSomething is broken. Auto assigns a BugZero manager.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions