Skip to content

[Due for payment 2026-10-22] [$175] Company card-there's no error appears above the assign button #102504

Closed

Description

@applause-bot

If you haven’t already, check out our contributing guidelines for onboarding. To join our Slack channel, fill out this form.


Version Number: v9.4.95-0
Reproducible in staging?: Yes
Reproducible in production?: Yes
If this was caught during regression testing, add the test name, ID and link from BrowserStack: #101963
Email or phone of affected tester (no customers): applausetester+piyoh@applause.expensifail.com
Issue reported by: Applause Internal Team
Bug source: Pull Request QA execution
Device used: Windows 11 / Chrome, iPhone 13 / iOS 27 Beta, Samsung Galaxy A52 / Android 14
App Component: Workspace Settings

Action Performed:

Preconditions:

  • sign in to applausetester@applause.expensifail.com as a domain admin
  • navigate to "DO NOT DELETE - New WS for Domain Card" workspace
  • go to member, choose an expensifail account that you have access to, add the member as workspace admin

Steps:

  1. sign in as the WS admin that already added to the workspace member in preconditions
  2. Navigate to "DO NOT DELETE - New WS for Domain Card" workspace
  3. Go to company card
  4. Click "assign" button on the card
  5. Pick any member, continue to the confirmation step, tap Assign

Expected Result:

the error appears above the Assign button.

Actual Result:

the error doesn't appears above the Assign button, and it does nothing, can't be assigned but no error message shown

Workaround:

Unknown

Platforms:

  • Android: App
  • Android: mWeb Chrome
  • iOS: App
  • iOS: mWeb Safari
  • iOS: mWeb Chrome
  • Windows: Chrome
  • MacOS: Chrome Safari

Screenshots/Videos

Bug7272064_1790640423234.bandicam_2026-09-29_06-45-28-554.1.mp4

View all open jobs on GitHub

Applause Internal Information
Exported by: Julia Ponikarchuk
Bug ID: 7272064

Upwork Automation - Do Not Edit
Issue OwnerCurrent Issue Owner: @truph01

Activity

  1. added
    BugSomething is broken. Auto assigns a BugZero manager.
    on Sep 29, 2026
  2. applause-bot commented on Sep 29, 2026

    @applause-bot
    Author

    While Applause doesn't embed attachments for this bug, here are the links for quick view:
    https://platform.applause.com/services/links/v1/external/392655638e9cf8a6a9aad1dabd8d78436fcbf1309fda2a549f77be527d1afc5a

  3. MelvinBot commented on Sep 29, 2026

    @MelvinBot
    Contributor

    Proposal

    What is the root cause of that problem?

    When the AssignCard request fails, the App never writes an error to the Onyx key that the confirmation step reads.

    • The confirmation step shows assignCard?.errors above the Assign button (ConfirmationStep.tsx:227-243).
    • assignWorkspaceCompanyCard's failureData only puts a generic error on the optimistic "card assigned" report action in the workspace owner's expense chat. It never sets ONYXKEYS.ASSIGN_CARD.errors (CompanyCards.ts:518-529).
    • finallyData resets isAssigning to false. So the button spins, goes back to normal, and nothing appears. That's the "does nothing" behavior.

    The error above the button only shows if the server response itself includes assignCard.errors, and in this case it doesn't. The translation key workspace.companyCards.assignCardFailedError ("Card assignment failed.") already exists but nothing uses it (en.ts:6509). Its sibling unassignCardFailedError is used in unassign's failureData.

    This isn't a regression from [Payment due @brunovjk] Clear the assign card error when leaving the confirmation step. That PR only clears errors when the screen unmounts, and on failure the screen stays mounted. The bug also reproduces on production.

    What changes do you think we should make in order to solve the problem?

    In assignWorkspaceCompanyCard in src/libs/actions/CompanyCards.ts, add a failureData entry that merges errors into ONYXKEYS.ASSIGN_CARD using getMicroSecondOnyxErrorWithTranslationKey('workspace.companyCards.assignCardFailedError'). Keep isAssigning: false in finallyData.

    The existing OfflineWithFeedback then shows the error above the Assign button. Dismissing it calls clearAssignCardErrors, and PR #101963's unmount cleanup clears it when the user leaves.

    Add a UI test in tests/ui/AssignCardFeed.tsx: when the assign request fails, the error appears above the Assign button.

    What alternative solutions did you explore? (Optional)

    Rely on the backend alone to return a specific assignCard.errors message, such as one explaining the permission requirement. That leaves every other failure silent. A better approach is to show the backend message when there is one, and fall back to the generic App error otherwise. Showing only one message needs a small check, because failureData merges into the same errors map after the response's Onyx data.

    Investigation details
    • A workspace admin can reach the confirmation step for a domain feed that is linked to the workspace (useIsAllowedToIssueCompanyCard.ts:26-28). submit() has no early return for this case, so the request goes out and the server rejects it.
    • Response handling applies the response's onyxData first, then failureData for any non-200 jsonCode, then finallyData (OnyxUpdates.ts:74-107).
    • The report-action error goes to the owner's expense chat (getPolicyExpenseChat(policy.ownerAccountID, ...), CompanyCards.ts:485). A non-owner admin won't see it.
    • I haven't confirmed from production logs what the server returns in this case. The App-side gap exists regardless.

    Next Steps for Contributor+ team:
    To accept: @MelvinBot implement [this](https://github.com/Expensify/App/issues/102504) to create a draft PR.
    To refine: @MelvinBot <your feedback>
    To reject: Explain why you are rejecting Melvin's proposal.


    view run

  4. added
    ExternalAdded to denote the issue can be worked on by a contributor
    on Sep 29, 2026
  5. melvin-bot commented on Sep 29, 2026

    @melvin-bot

    Triggered auto assignment to Contributor-plus team member for initial proposal review - @truph01 (External)

  6. changed the title [-]Company card-there's no error appears above the assign button[/-] [+][$175] Company card-there's no error appears above the assign button[/+] on Sep 29, 2026
  7. melvin-bot commented on Sep 29, 2026

    @melvin-bot
  8. bonnhatnguyen commented on Sep 29, 2026

    @bonnhatnguyen

    Proposal

    Please re-state the problem that we are trying to solve in this issue.

    When assigning a company card from a workspace fails (e.g., when a workspace admin attempts to assign a card on a domain feed where permissions are insufficient), the Assign button stops loading, nothing happens, and no error message appears above the Assign button.

    What is the root cause of that problem?

    1. In src/pages/workspace/companyCards/assignCard/ConfirmationStep.tsx:227-243, the confirmation step renders errors from assignCard?.errors wrapped inside OfflineWithFeedback directly above the Assign button:
      <OfflineWithFeedback
          errors={assignCard?.errors}
          onClose={clearAssignCardErrors}
      >
    2. In src/libs/actions/CompanyCards.ts:462-540, assignWorkspaceCompanyCard manages the optimistic and failure state:
      • In optimisticData: It sets ONYXKEYS.ASSIGN_CARD: {isAssigning: true}.
      • In finallyData: It resets ONYXKEYS.ASSIGN_CARD: {isAssigning: false}.
      • In failureData (lines 518–529): It only sets an error on the optimistic report action in the policy owner's chat (policyExpenseChat?.reportID).
    3. Critically, failureData never writes an error object to ONYXKEYS.ASSIGN_CARD.
    4. When the API call fails on the server, finallyData flips isAssigning back to false, but because assignCard?.errors was never populated, ConfirmationStep has no error data to render. Consequently, the button returns to its idle state without giving any visible feedback or error message to the user.

    What changes do you think we should make in order to solve the problem?

    1. Populate errors on ONYXKEYS.ASSIGN_CARD in failureData:
      • In src/libs/actions/CompanyCards.ts inside assignWorkspaceCompanyCard:
        Add an entry in failureData to write a failure error to ONYXKEYS.ASSIGN_CARD using the existing translation key workspace.companyCards.assignCardFailedError:
        failureData: [
            {
                onyxMethod: Onyx.METHOD.MERGE,
                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${policyExpenseChat?.reportID}`,
                value: {
                    [optimisticCardAssignedReportAction.reportActionID]: {
                        pendingAction: null,
                        errors: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('common.genericErrorMessage'),
                    },
                },
            },
            {
                onyxMethod: Onyx.METHOD.MERGE,
                key: ONYXKEYS.ASSIGN_CARD,
                value: {
                    errors: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('workspace.companyCards.assignCardFailedError'),
                },
            },
        ],
      • This ensures that if the server returns an error or fails, assignCard.errors receives the error timestamp map, immediately triggering OfflineWithFeedback to render the localized error alert above the Assign button.
    2. Add UI Test Coverage in tests/ui/AssignCardFeed.tsx:
      • Simulate a failed AssignCompanyCard API call.
      • Verify that the error message renders properly above the Assign button and that dismissing it calls clearAssignCardErrors.

    What alternative solutions did you explore? (Optional)

    • Relying solely on backend error response: If the backend does not return specific field errors in jsonCode, relying only on the server response leaves failures silent. Adding failureData guarantees predictable, resilient client-side error feedback while still letting server-provided errors merge if present.

    Contributor details
    Your Expensify account email: bonnhatnguyen0@gmail.com
    Upwork Profile Link: https://www.upwork.com/freelancers/~0139ed4098bdc50182

  9. melvin-bot commented on Sep 29, 2026

    @melvin-bot

    ✅ Contributor details stored successfully. Thank you for contributing to Expensify!

  10. franklincg commented on Sep 29, 2026

    @franklincg

    Proposal

    Root cause

    The confirmation screen already renders feedback from ONYXKEYS.ASSIGN_CARD.errors, but the failed assign request never writes an error there.

    assignWorkspaceCompanyCard sets isAssigning: true optimistically and clears it in finallyData. On failure, the current failureData only attaches a generic error to the optimistic report action in the workspace expense chat. It does not populate ASSIGN_CARD.errors.

    That leaves the exact reported behavior: loading stops, but the confirmation step has no error state to display.

    Fix

    Update the failure path for assignWorkspaceCompanyCard so it also writes the existing workspace.companyCards.assignCardFailedError message to `ONYXKEYS.ASSIGN

  11. truph01 commented on Sep 30, 2026

    @truph01
    Contributor

    @MelvinBot Implement this PR so that i can test your solution. It looks promise

  12. MelvinBot commented on Sep 30, 2026

    @MelvinBot
    Contributor

    🤖 Draft PR created: Show an error above the Assign button when company card assignment fails
    Please mark it as "Ready for review" when it is ready for review.

    The PR follows the proposal:

    • When the AssignCompanyCard request fails, "Card assignment failed." now shows above the Assign button.
    • A retry clears the old error first, so the message doesn't show twice.
    • A new unit test covers both cases. It fails without the fix and passes with it.

    Lint, typecheck, spell check, and the existing AssignCardFeed UI tests all pass.

    To test, follow the issue's steps as a non-owner workspace admin on the domain feed. After you tap Assign, "Card assignment failed." should appear above the button.

  13. 20 remaining items

  14. added
    Awaiting PaymentAuto-added when associated PR is deployed to production
    and removed on Oct 21, 2026
  15. melvin-bot commented on Oct 21, 2026

    @melvin-bot

    Triggered auto assignment to @mallenexpensify (Awaiting Payment)

  16. melvin-bot commented on Oct 21, 2026

    @melvin-bot

    Payment Summary

    Resolving PRs:

    BugZero Checklist (@mallenexpensify)

    • I have confirmed assignees, roles, and Upwork contracts look correct
    • I have paid out Upwork contracts / manual NewDot requests
    • [BugZero Assignee] I have created a GH issue for creating/updating the regression test once above steps have been agreed upon
  17. mallenexpensify commented on Oct 24, 2026

    @mallenexpensify
    Contributor

    @truph01 plz fully fill out the C+ Checklist

    Image
  18. truph01 commented on Oct 26, 2026

    @truph01
    Contributor

    @mallenexpensify I updated checklist

  19. mallenexpensify commented on Oct 26, 2026

    @mallenexpensify
    Contributor

    Payment Summary

    Contributor+: @truph01 due $175 via NewDot

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

Metadata

Metadata

Labels

Awaiting PaymentAuto-added when associated PR is deployed to productionBugSomething is broken. Auto assigns a BugZero manager.DailyKSv2ExternalAdded to denote the issue can be worked on by a contributor

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions