Skip to content

[$175] Workspace - No error shown when saving a report field with an invalid formula #104067

Open

Description

@melvin-bot

Problem

When you save a workspace report field whose default value has an invalid formula, the save fails silently. The new field disappears from the list and no error appears.

Reproducible in production

Yes

Action Performed

  1. Open Workspace settings > Report fields.
  2. Add a report field.
  3. Enter an invalid formula in Default value, such as {field:DoesNotExist}.
  4. Save the report field.

Expected Result

The save fails and the report fields page shows an error explaining that the formula is invalid.

Actual Result

The save fails, but no error is shown. The newly added report field disappears from the list.

Cause

The server correctly rejects the invalid formula. The App then fails to show that rejection:

  1. The report field form doesn't check whether a {field:...} reference points to an existing field, so the request is sent to the server.
  2. When the server rejects it, the App rolls back the optimistic field and stores the error on the policy's errorFields.fieldList.
  3. Nothing on the report fields page reads or displays that error, so the user gets no feedback.

Suggested fix

  • Show the stored errorFields.fieldList error on the report fields page, so server rejections are visible and dismissible.
  • Optionally, validate {field:...} references in the form before saving, so this case is caught client-side.

Workaround

Unknown

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

Activity

  1. added
    BugSomething is broken. Auto assigns a BugZero manager.
    on Oct 15, 2026
  2. MelvinBot commented on Oct 15, 2026

    @MelvinBot
    Contributor

    Proposal

    Updated 2026-10-22: Updated based on feedback from shubham1206agra. The backend now returns the specific error keyed to the failed field, so this version reads that error and shows it on the field's own row.

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

    When you save a report field whose default value has an invalid formula, such as {field:DoesNotExist}, the save fails. The new field disappears and no error appears.

    What is the root cause of that problem?

    The backend now returns the error in this shape. The App already uses this shape for the report title error:

    errorFields.fieldList.<fieldKey>.defaultValue.<microtime>: "Formula field {field:DoesNotExist} not recognized"
    

    The App doesn't use it:

    • On failure, createReportField removes the field from policy.fieldList, so its row disappears. It also writes only a generic error to errorFields[fieldKey].
    • In WorkspaceFieldsSection, each row's OfflineWithFeedback gets only pendingAction. Nothing reads errorFields.fieldList[fieldKey] or errorFields[fieldKey].

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

    Show the error on the failed field's row, as Categories and Tags do.

    1. Keep the failed row. In createReportField's failureData, keep the policy field with pendingAction: ADD instead of setting it to null. Keep removing it from each report's fieldList, as the code does today. Keep the generic errorFields[fieldKey] error as a fallback.
    2. Show the error on the row. In WorkspaceFieldsSection, give each row:
      • errors: the backend error, read with getLatestErrorField({errorFields: policy?.errorFields?.fieldList?.[fieldKey] ?? {}}, 'defaultValue'). If that is empty, use getLatestErrorField(policy, fieldKey).
      • onClose: call a new clearReportFieldErrors(policy, fieldID).
    3. Add clearReportFieldErrors in ReportField.ts:
      • Clear errorFields.fieldList[fieldKey] and errorFields[fieldKey].
      • If the field's pendingAction is ADD, remove it from fieldList. This mirrors clearCategoryErrors.
    4. Keep failed fields off reports. getAvailableReportFields merges every policy field into unsettled reports. Skip policy fields that have pendingAction: ADD and are not on the report already. Optimistic adds are written to each report's fieldList, so they still appear.
    5. Clear errors narrowly. In createReportField and updateReportFieldInitialValue, the optimistic and success data set errorFields: null, which wipes every policy error, including the title error. Clear only {[fieldKey]: null, fieldList: {[fieldKey]: null}}.

    updateReportFieldInitialValue already keeps the row and reverts the value on failure. After steps 2 and 3, its server error also appears on the row.

    What alternative solutions did you explore? (Optional)

    • Show failures at the top of the section. Keep removing the field, and show any errorFields.fieldList key that has no matching field. This avoids step 4, but the field's name is lost, so the user can't tell which field failed.
    • Validate in the form. Flag unknown {field:X} references in CreateFieldsPage and FieldsInitialValuePage before saving. This is optional now, because the server returns a clear message.
    Code references

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

  3. added
    ExternalAdded to denote the issue can be worked on by a contributor
    on Oct 15, 2026
  4. melvin-bot commented on Oct 15, 2026

    @melvin-bot
    Author

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

  5. changed the title [-]Workspace - No error shown when saving a report field with an invalid formula[/-] [+][$175] Workspace - No error shown when saving a report field with an invalid formula[/+] on Oct 15, 2026
  6. melvin-bot commented on Oct 15, 2026

    @melvin-bot
    Author
  7. ashu75575 commented on Oct 15, 2026

    @ashu75575
    Contributor

    Proposal

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

    When a workspace report field is saved with an invalid formula as its default value (for example {field:DoesNotExist}), the save fails silently. The new field disappears from the list and no error is shown.

    What is the root cause of that problem?

    Two things combine here:

    1. validateForm in CreateReportFieldsPage checks length, circular references and unsupported {report:...} parts, but not whether a {field:...} reference points to an existing field. The invalid value passes the form and is sent to the server.
    2. When the server rejects it, the failureData in createReportField sets fieldList[fieldKey] to null, which removes the row, and writes the error to errorFields[fieldKey]. The row in WorkspaceReportsPage is rendered in an OfflineWithFeedback with only pendingAction (no errors or onClose), and nothing else on the page reads that error. The row disappears and the error is never displayed.

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

    Keep the failed row on the page with its error, the same way categories already do it.

    1. In createReportField's failureData, keep the optimistic field with pendingAction: add and set errors on it (generic failure message), instead of setting it to null.
    2. In WorkspaceReportsPage, pass the row's errors and an onClose handler to its OfflineWithFeedback.
    3. Add a clearReportFieldErrors(policyID, fieldKey) action that mirrors clearCategoryErrors. If the field's pendingAction is add, remove it from fieldList. Otherwise, only clear its errors.

    The user then sees the failed field with a red error, and clicking the X removes it. This covers every server-side rejection, not just formulas.

    What alternative solutions did you explore? (Optional)

    Validate the formula in the form before the API call. In validateForm, parse the default value with the existing parse from libs/Formula and show an inline error on the default value input for common invalid cases:

    • {field:X} where no field named X exists in policy.fieldList
    • {field:} with an empty field name
    • an opening { without a matching }
  8. camesenin commented on Oct 15, 2026

    @camesenin

    Proposal

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

    In Workspace Settings > More features > Report fields, when creating a new report field with an invalid formula default value (e.g. {field:DoesNotExist}), saving the field fails silently. The newly created report field disappears completely from the list and no error message is displayed to the user.

    What is the root cause of that problem?

    1. Destructive Failure Data in Action:
      In src/libs/actions/Policy/ReportField.ts (createReportField, lines 256–268), failureData deletes the optimistic field by setting fieldList: {[fieldKey]: null} while simultaneously writing the failure message to policy.errorFields[fieldKey].
    2. List Rendering Disconnect in WorkspaceFieldsSection.tsx:
      In src/pages/workspace/fields/WorkspaceFieldsSection.tsx (lines 136–181), menu items are mapped strictly from Object.values(policy.fieldList). Because failureData deleted the field from fieldList, no row exists in the DOM. Furthermore, WorkspaceFieldsSection.tsx never reads policy.errorFields for field keys, nor does it pass errors or an onClose callback to OfflineWithFeedback for field items. Consequently, the error is orphaned in Onyx and the field silently disappears.

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

    1. In src/libs/actions/Policy/ReportField.ts:
      Update createReportField's failureData to retain the field in fieldList with errors attached instead of unmounting it to null, following Expensify's standard pattern (mirrored in Categories and Tags):

      const failureData: Array<OnyxUpdate<typeof ONYXKEYS.COLLECTION.POLICY>> = [
          {
              key: `${ONYXKEYS.COLLECTION.POLICY}${policy?.id}`,
              onyxMethod: Onyx.METHOD.MERGE,
              value: {
                  fieldList: {
                      [fieldKey]: {
                          ...optimisticReportFieldDataForPolicy,
                          errors: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('workspace.reportFields.genericFailureMessage'),
                      },
                  },
              },
          },
      ];
    2. In src/pages/workspace/fields/WorkspaceFieldsSection.tsx:
      In getMenuItems, pass errors={field.errors} and an onClose handler to OfflineWithFeedback for each report field row:

      • When dismissed via onClose, call a helper clearReportField(policyID, fieldKey). If field.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, it removes the field from fieldList ([fieldKey]: null); otherwise, it clears errors: null.
    3. In src/libs/actions/Policy/ReportField.ts:
      Export clearReportField(policyID: string, fieldKey: string) to cleanly dismiss the error and unlink failed optimistic additions from Onyx.

    What alternative solutions did you explore? (Optional)

    Displaying orphaned errorFields in a banner at the top of WorkspaceFieldsSection. However, keeping the failed item in-line with OfflineWithFeedback (and a red brick road indicator) preserves context for which field failed and provides a consistent UX matching Workspace Categories and Tags.

    Contributor details
    Your Expensify account email: camesenin@gmail.com
    Upwork Profile Link: https://www.upwork.com/freelancers/~0170d6b02e9440e604

  9. melvin-bot commented on Oct 15, 2026

    @melvin-bot
    Author

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

  10. janiya2 commented on Oct 15, 2026

    @janiya2

    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 Workspace Settings > Report fields, when adding or editing a report field with a default value formula containing a reference to a non-existent field (e.g. {field:DoesNotExist}), saving fails silently. The newly created report field disappears completely from the list and no error message is displayed to the user.

    What is the root cause of that problem?

    There are two interrelated root causes spanning client validation and failure handling:

    1. Client-side formula validation ignores {field:...} tokens:
      In src/pages/workspace/fields/CreateFieldsPage.tsx (validateForm), formula validation only checks for circular references (hasCircularReferences) and unsupported {report:...} parts (getUnsupportedReportFieldFormulaParts).
      In src/libs/WorkspaceReportFieldUtils.ts (getUnsupportedReportFieldFormulaParts), only tokens of type FORMULA_PART_TYPES.REPORT are checked (if (part.type !== FORMULA_PART_TYPES.REPORT) continue;). Tokens of type FORMULA_PART_TYPES.FIELD are ignored. Therefore, references to non-existent fields like {field:DoesNotExist} pass client-side validation as valid and are dispatched to the server via createReportField.

    2. Destructive failureData & Missing Section Error Display:
      When the server rejects the invalid formula, the App applies failureData in src/libs/actions/Policy/ReportField.ts (createReportField):

      fieldList: {
          [fieldKey]: null,
      },
      errorFields: {
          [fieldKey]: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('workspace.reportFields.genericFailureMessage'),
      },

      Setting fieldList[fieldKey]: null removes the optimistic report field completely from policy.fieldList. Meanwhile, src/pages/workspace/fields/WorkspaceFieldsSection.tsx only renders items that exist in policy.fieldList (Object.values(fieldList).filter(...)) and its renderItem only passes pendingAction={item.pendingAction} to OfflineWithFeedback. It never reads or displays policy.errorFields.
      Consequently, when the server rejects the request, the item is deleted from the UI with zero error message rendered.

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

    1. Validate {field:...} references on the client (WorkspaceReportFieldUtils.ts & CreateFieldsPage.tsx):

    In src/libs/WorkspaceReportFieldUtils.ts, add a helper getInvalidReportFieldFormulaParts(initialValue?: string, fieldList?: Record<string, PolicyReportField>, expectedTarget?: ValueOf<typeof CONST.REPORT_FIELD_TARGETS>):

    • Parse the formula using Formula.parse(initialValue).
    • For parts of type FORMULA_PART_TYPES.FIELD: extract the referenced field name from part.fieldPath[0].
    • Verify whether the referenced field exists in the available fields for this policy and target (using getReportFieldsForTarget(fieldList, expectedTarget) and checking by name or fieldID).
    • If referenced field is missing, return the invalid token(s).

    In CreateFieldsPage.tsx -> validateForm:

    if ((type === CONST.REPORT_FIELD_TYPES.TEXT || type === CONST.REPORT_FIELD_TYPES.FORMULA) && !!formInitialValue && !errors[INPUT_IDS.INITIAL_VALUE]) {
        const invalidFieldParts = getInvalidReportFieldFormulaParts(formInitialValue, policy?.fieldList, fieldTarget);
        if (invalidFieldParts.length > 0) {
            errors[INPUT_IDS.INITIAL_VALUE] = translate('workspace.reportFields.invalidFormulaFieldReferenceError', invalidFieldParts.join(', '));
        }
    }

    This catches the error immediately on form submission and displays an inline error under the Default Value field without sending an invalid request to the server.

    2. Display server failure errors in WorkspaceFieldsSection.tsx:

    In src/pages/workspace/fields/WorkspaceFieldsSection.tsx, wrap the list or section with an OfflineWithFeedback or render a dismissible error banner bound to policy?.errorFields for report fields:

    <OfflineWithFeedback
        errors={policy?.errorFields}
        onClose={(errorKey) => clearReportFieldError(policyID, errorKey)}
    >
    ...
    </OfflineWithFeedback>

    And add clearReportFieldError in ReportField.ts to clear policy.errorFields[fieldKey].

    What alternative solutions did you explore?

    Only relying on server error display without client validation would create unnecessary network roundtrips and optimistic UI flickering (field appearing and disappearing). Validating on the client side provides immediate UX feedback while adding section error display ensures robustness for any other server-side rejection.

  11. melvin-bot commented on Oct 15, 2026

    @melvin-bot
    Author

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

  12. taieddie commented on Oct 15, 2026

    @taieddie

    Contributor details
    Your Expensify account email: taieddie8@gmail.com
    Upwork Profile Link: https://www.upwork.com/freelancers/~01e51b3f9ff738cf94

    Proposal

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

    When creating a workspace report field with an invalid formula default value (such as {field:DoesNotExist}), the form submits the request to the server without validating {field:...} references. When the server rejects the request, the optimistic field is removed from the list and no error message is shown on screen.

    What is the root cause of that problem?

    1. Client-Side Formula Reference Validation Gap:
      In src/pages/workspace/fields/CreateFieldsPage.tsx (validateForm), formula validation calls getUnsupportedReportFieldFormulaParts(formInitialValue). In src/libs/WorkspaceReportFieldUtils.ts, getUnsupportedReportFieldFormulaParts only checks tokens of type FORMULA_PART_TYPES.REPORT ({report:...}) and skips FORMULA_PART_TYPES.FIELD ({field:...}). As a result, references to non-existent fields like {field:DoesNotExist} bypass form validation and are sent to the server.

    2. Unrendered Failure Error on Report Fields Section:
      When createReportField in src/libs/actions/Policy/ReportField.ts fails on the server, failureData removes the optimistic field (fieldList[fieldKey]: null) and writes the error to policy.errorFields[fieldKey]. Because the field is removed from policy.fieldList, WorkspaceFieldsSection.tsx no longer renders a row for it, and WorkspaceFieldsSection.tsx never passes errors or onCloseError to ToggleSettingOptionRow. The field disappears silently while leaving an orphaned error key on policy.errorFields.

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

    1. Validate {field:...} References in src/libs/WorkspaceReportFieldUtils.ts:

      • Update the dynamic require type for FORMULA_PART_TYPES in getUnsupportedReportFieldFormulaParts to {REPORT: string; FIELD: string} and add an optional second parameter availableFields?: Record<string, PolicyReportField>.
      • When part.type === FORMULA_PART_TYPES.FIELD and availableFields !== undefined, extract const [fieldName] = part.fieldPath ?? [] and normalize with const normalizedReferencedName = fieldName?.toLowerCase() (matching the case-insensitive lookup without trimming in Formula.ts:468 and ReportUtils.ts:14962). If !normalizedReferencedName or no field in Object.values(availableFields) has field.name.toLowerCase() === normalizedReferencedName, push part.definition to unsupported.
    2. Enforce Field Reference Validation in CreateFieldsPage.tsx and FieldsInitialValuePage.tsx:

      • In CreateFieldsPage.tsx (validateForm), inside the existing (type === CONST.REPORT_FIELD_TYPES.TEXT || type === CONST.REPORT_FIELD_TYPES.FORMULA) && !!formInitialValue && !errors[INPUT_IDS.INITIAL_VALUE] guard, compute const targetFields = getReportFieldsForTarget(policy?.fieldList, fieldTarget) and pass targetFields into getUnsupportedReportFieldFormulaParts(formInitialValue, targetFields).
      • Apply the same check in FieldsInitialValuePage.tsx (validateForm) behind !errors[INPUT_IDS.INITIAL_VALUE] when reportField?.type is TEXT or FORMULA and !!formInitialValue, passing getReportFieldsForTarget(policy?.fieldList, expectedTarget) into getUnsupportedReportFieldFormulaParts(formInitialValue, targetFields) and setting errors[INPUT_IDS.INITIAL_VALUE] = translate('workspace.reportFields.unsupportedFormulaValueError', unsupportedFormulaParts.join(', ')). Because getReportFieldsForTarget returns {} when policy?.fieldList is empty or undefined, {field:DoesNotExist} is rejected even on workspaces with zero existing fields, while keeping circular reference errors higher priority.
    3. Scope and Render Section Failure Errors in ReportField.ts and WorkspaceFieldsSection.tsx:

      • In src/libs/actions/Policy/ReportField.ts (createReportField), define const sectionErrorKey = isInvoiceField ? 'invoiceFieldsError' : 'reportFieldsError'.
      • In optimisticData and successData, clear errorFields: {[sectionErrorKey]: null} instead of wiping the entire errorFields object (preserving unrelated policy toggle or report title errors).
      • In failureData, set fieldList: {[fieldKey]: null} and write the error exclusively to errorFields: {[sectionErrorKey]: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('workspace.reportFields.genericFailureMessage')} (omitting [fieldKey] so dismissing the banner leaves no orphaned red-brick-road badge on the workspace).
      • In src/pages/workspace/fields/WorkspaceFieldsSection.tsx, derive const sectionErrorKey = titleKey === 'workspace.common.invoiceFields' ? 'invoiceFieldsError' : 'reportFieldsError' and pass errors={policy?.errorFields?.[sectionErrorKey] ?? undefined} and onCloseError={() => clearPolicyErrorField(policyID, sectionErrorKey)} to ToggleSettingOptionRow.

    What alternative solutions did you explore? (Optional)

    I considered scanning policy.errorFields for keys starting with expensify_ that are missing from policy.fieldList. However, because WorkspaceFieldsSection renders both Expense Report Fields and Invoice Fields, and failureData deletes fieldList[fieldKey] (removing field.target), prefix scanning cannot distinguish whether a failed creation belonged to Expense Report Fields or Invoice Fields. I also considered keeping rejected fields inside policy.fieldList with pendingAction: ADD, but retaining server-rejected entries in policy.fieldList exposes invalid fields to downstream pickers and formula resolvers. Dedicated reportFieldsError and invoiceFieldsError keys isolate both sections cleanly.

    Test Plan

    Preconditions:

    • Log into an account with admin access to a Control workspace with Report Fields enabled.

    Manual Verification:

    1. Navigate to Workspace settings > Report fields > Add report field, set Type to Formula, enter {field:DoesNotExist} as the Default value, and click Save. Verify an inline error ("Formula field {field:DoesNotExist} not recognized") blocks submission without sending a network request.
    2. Create a text field named Department, then create a formula field with {field:department} and verify case-insensitive matching succeeds. Edit its initial value to {field:Ghost} and verify inline validation blocks saving.
    3. Simulate a server failure on CreatePolicyReportField and verify the error banner appears on the Report Fields section header, does not bleed into Invoice Fields, and clears cleanly with no residual workspace RBR badge when dismissed.

    Regression Verification:

    1. Verify circular reference formulas still display the circular reference error first.
    2. Verify existing report field creation, initial value editing, deletion, and report title settings (errorFields.fieldList) continue working without regressions, and run npm run test tests/unit/WorkspaceReportFieldUtilsTest.ts.
  13. melvin-bot commented on Oct 15, 2026

    @melvin-bot
    Author

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

  14. 12 remaining items

  15. dukenv0307 commented on Oct 20, 2026

    @dukenv0307
    Contributor

    @MelvinBot create an issue in E/E then assign me

  16. MelvinBot commented on Oct 20, 2026

    @MelvinBot
    Contributor

    Done, dukenv0307. I created an internal issue for the backend change and assigned it to you.

    It asks the backend to return report field save errors keyed to the specific field, not the generic errorFields.fieldList key. The App can then show the error on the failed field's row.


    view run

  17. dukenv0307 commented on Oct 22, 2026

    @dukenv0307
    Contributor

    BE PR is deployed to staging

  18. shubham1206agra commented on Oct 22, 2026

    @shubham1206agra
    Contributor

    @dukenv0307 Maybe you put the error too deep. @MelvinBot Can you check and confirm this?

    {
        "code": 666,
        "jsonCode": 666,
        "type": "Expensify\\Libs\\Error\\ExpError",
        "UUID": "1A68E442-5F40-440B-9A37-405C0DFC9471",
        "message": "Formula field {field:DoesNotExist} not recognized",
        "title": "",
        "data": {
            "field_id_LO": [
                "Formula field {field:DoesNotExist} not recognized"
            ],
            "onyxData": [
                {
                    "onyxMethod": "merge",
                    "key": "policy_5B0B81C5BF426725",
                    "value": {
                        "errorFields": {
                            "fieldList": {
                                "expensify_field_id_LO": {
                                    "defaultValue": {
                                        "1792680689003780": "Formula field {field:DoesNotExist} not recognized"
                                    }
                                }
                            }
                        }
                    }
                }
            ]
        },
        "htmlMessage": "",
        "onyxData": [
            {
                "onyxMethod": "merge",
                "key": "policy_5B0B81C5BF426725",
                "value": {
                    "errorFields": {
                        "fieldList": {
                            "expensify_field_id_LO": {
                                "defaultValue": {
                                    "1792680689003780": "Formula field {field:DoesNotExist} not recognized"
                                }
                            }
                        }
                    }
                }
            }
        ],
        "requestID": "a4e952006ced8af8-DEL"
    }
  19. MelvinBot commented on Oct 22, 2026

    @MelvinBot
    Contributor

    No, the error isn't nested too deep. The new response uses the same shape the App already uses for the report title field error:

    errorFields.fieldList.<fieldKey>.defaultValue.<microtime>

    The key also matches what the App generates. A field named "lo" gets expensify_field_id_LO from generateFieldID and getReportFieldKey.

    Evidence and App-side follow-up
    • The title field writes its error in this shape: Policy.ts:7300-7306.
    • The App reads it with getLatestErrorField({errorFields: policy?.errorFields?.fieldList?.[key] ?? {}}, 'defaultValue'): WorkspaceReportsPage.tsx:67-68.
    • A report field can use the same read with its own fieldKey. To clear it, merge errorFields.fieldList[fieldKey] = null, as clearPolicyTitleFieldError does.

    On the App side, createReportField's failureData still writes a generic error to errorFields[fieldKey]. It also removes the field from fieldList, so the field's row disappears (ReportField.ts:256-268). The App fix should read the new path. It should also keep the failed row, or show the error elsewhere on the page.


    view run

  20. shubham1206agra commented on Oct 22, 2026

    @shubham1206agra
    Contributor

    @MelvinBot Update the proposal

  21. MelvinBot commented on Oct 22, 2026

    @MelvinBot
    Contributor

    I updated my proposal. It now uses the new backend error at errorFields.fieldList[fieldKey].defaultValue.

    • Keep the failed row: On failure, the new field stays in the list with pendingAction: ADD instead of being removed.
    • Show the error on the row: The row shows the server message, such as "Formula field {field:DoesNotExist} not recognized." If the server sends no message, the row shows the generic error.
    • Dismiss: Dismissing the error clears it and removes the failed field, as Categories do.
    • Keep failed fields off reports: Failed fields don't show on unsettled reports while they wait to be dismissed.
    • Clear errors narrowly: Saving clears only that field's errors, not every policy error.

    view run

  22. emkhalid commented on Oct 22, 2026

    @emkhalid
    Contributor

    @shubham1206agra Thank you for the clarification in your comment above!

    I tested MelvinBot’s approach locally and noticed a few clear issues:

    1. The dismiss button does not work: When you click the (X) to close the error banner, the error stays on the screen, and the red dot next to the workspace never goes away.
    The.dismiss.button.does.not.work.webm
    1. The field completely disappears: When saving fails, the field vanishes from the list, and a disconnected error message is dumped at the top of the page.
    The.field.completely.disappears.webm
    1. Generic error message: It only shows a generic failure message instead of telling the user what actually went wrong with the formula.
    Image
    1. Too many file changes: Melvin modifies 4 files with extra duplicate validation code, making it harder to review.

    How My Solution Fixes This (Standard Expensify Design)

    • Minimal & Clean: Touches only 2 files instead of 4, keeping the fix small and easy to review.

    • The field stays visible: Just like Categories and Tags, the failed field remains in the list with a red dot so the user can see what failed.

    • Shows the real error: It displays the exact message from the server (e.g., "Formula field {field:DoesNotExist} not recognized").

    • Working dismiss button: Clicking (X) cleanly closes the error, removes the failed field, and clears the red dot immediately.

    Fix demo

    fixDemo104067.webm

    Would you like me to share the full proposal ?

  23. shubham1206agra commented on Oct 25, 2026

    @shubham1206agra
    Contributor
  24. MelvinBot commented on Oct 25, 2026

    @MelvinBot
    Contributor

    🤖 Draft PR created: Show report field save errors on the field's row
    Please mark it as "Ready for review" or ask me to do that for you when it is ready for review.

    It implements the proposal:

    • A field that fails to save stays in the list, with the server error on its row.
    • Dismissing the error removes the failed field.
    • Failed fields stay off reports.
    • Saving clears only that field's errors, so the report title error is kept.

    Typecheck, lint, spell check, and the related unit tests pass. The web browser test was blocked because the test session showed a blank page, so please verify the flow manually.


    view run · no recording available

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.ExternalAdded to denote the issue can be worked on by a contributorInternalRequires API changes or must be handled by Expensify staffReviewingHas a PR in reviewWeeklyKSv2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions