Skip to content

[$175] Tags - Not here page opens after editing custom tag name from uploaded CSV #105001

Open

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: 9.5.20-0
Reproducible in staging?: Yes
Reproducible in production?: N/A - new feature, doesn't exist in prod
If this was caught during regression testing, add the test name, ID and link from BrowserStack: #103359
Email or phone of affected tester (no customers): [email protected]
Issue reported by: Applause Internal Team
Bug source: Exploratory - Significant User Experience Deterioration
Device used: Mac 26.5 / Chrome
App Component: Workspace Settings

Action Performed:

Precondition:

  • Use expensifail account and enable indirectTagUploads beta
  • Connect to NetSuite.
  1. Go to staging.new.expensify.com
  2. Go to workspace settings > Accounting.
  3. Click Import > Departments > Tag.
  4. Go to Tags.
  5. Click More > Append custom tag list.
  6. Upload multi level tag CSV.
  7. Open Department tag from the uploaded CSV.
  8. Click Custom tag name.
  9. Edit name and save it.

Expected Result:

Name will be saved without issue.

Actual Result:

Not here page opens after editing custom tag name from uploaded CSV.

Workaround:

Unknown

Platforms:

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

Screenshots/Videos

Independent.-.Multi.Level.tags.csv

Bug7295634_1792864463064.22.mp4

View all open jobs on GitHub

Applause Internal Information
Exported by: Mita Rachim
Bug ID: 7295634

Upwork Automation - Do Not Edit

Activity

  1. added
    DeployBlockerCashThis issue or pull request should block deployment
    BugSomething is broken. Auto assigns a BugZero manager.
    on Oct 26, 2026
  2. melvin-bot commented on Oct 26, 2026

    @melvin-bot

    You have been assigned to this deploy blocker because you recently merged this PR: #103359

  3. melvin-bot commented on Oct 26, 2026

    @melvin-bot

    @yuwenmemon @suneox you have been assigned to this deploy blocker because you reviewed the offending PR: #103359

  4. melvin-bot commented on Oct 26, 2026

    @melvin-bot

    💬 A slack conversation has been started in #expensify-open-source

  5. github-actions commented on Oct 26, 2026

    @github-actions
    Contributor

    👋 Friendly reminder that deploy blockers are time-sensitive ⏱ issues! Check out the open `StagingDeployCash` deploy checklist to see the list of PRs included in this release, then work quickly to do one of the following:

    1. Identify the pull request that introduced this issue and revert it.
    2. Find someone who can quickly fix the issue.
    3. Fix the issue yourself.
  6. MelvinBot commented on Oct 26, 2026

    @MelvinBot
    Contributor

    Deploy Blocker Investigation

    Causing PR (medium confidence): Add Append custom tag list for accounting-connected workspaces on the indirectTagUploads beta. It is the only PR in Deploy Checklist: New Expensify 2026-10-23 that makes this flow reachable. Before it, connected workspaces could not add a custom tag list next to their NetSuite lists.

    Recommendation: revert 103359. The PR is self-contained and behind the indirectTagUploads beta, so the revert should be clean. A fix forward isn't practical yet. The tag-list data that breaks the page comes from the server, so the App fix depends on what the server returns.

    Why "Not here" shows: Every page in this flow finds the tag list by the orderWeight number in the URL, not by name. After the rename, no tag list has that orderWeight, so the list page shows NotFoundPage.

    Investigation details

    All links are at 21045e266fdb050a4761b043e0350ef903f8888b.

    1. The routes are workspace-tag-list/:orderWeight and workspace-edit-tags/:orderWeight: src/ROUTES.ts:1271-1288.
    2. The list page looks up the list with getTagListName(policyTags, orderWeight): DynamicWorkspaceViewTagsPage.tsx:65-66. That needs an exact tag.orderWeight === orderWeight match (src/libs/PolicyUtils/tag.ts:27-33). If nothing matches, it renders NotFoundPage (DynamicWorkspaceViewTagsPage.tsx:202-204).
    3. After saving, the rename page goes back to workspace-tag-list/<orderWeight>: DynamicWorkspaceEditTagsPage.tsx:61-70.
    4. The optimistic update in renamePolicyTagList keeps orderWeight when it moves the list to the new key (src/libs/actions/Policy/Tag.ts:984-994). It sends tagListIndex: orderWeight to RenamePolicyTaglist (Tag.ts:1022-1029). The local update alone can't cause the bug.
    5. 103359 doesn't touch the rename code. It adds no optimistic tag lists. It only passes appendToExistingLists to ImportMultiLevelTags, so the server assigns the appended lists' orderWeight values.

    Likely mechanism (unconfirmed): The appended lists' orderWeight values clash with the NetSuite list or don't match the server's list positions. The RenamePolicyTaglist response then returns the renamed list with a different orderWeight. The CSV's first column is "Department", the same name as the NetSuite import, which makes a clash plausible.

    Risk: If two lists share an orderWeight, getTagListName returns the first match. The rename could then send the wrong tagListIndex and rename the NetSuite list.

    Other PRs ruled out: I checked the file lists of all PRs in the checklist. Skip already escaped colons when escaping tag names only changes escapeTagName, which the rename doesn't use. No other PR touches tags or these routes.

    Not tested in the UI: The repro needs an expensifail account with NetSuite connected and the beta enabled.

    Before deciding, you can check:

    1. Compare the policyTags_<policyID> data (key, name, orderWeight) after the append and after the rename. Also check the RenamePolicyTaglist response.
    2. On staging, refresh after the rename and check which list was renamed. If only navigation breaks and the right list is renamed, you can demote instead of reverting. Don't demote if the NetSuite list gets renamed.

    Assignees are already correct. I skipped the code review rule because the mechanism depends on server data.


    view run

  7. suneox commented on Oct 26, 2026

    @suneox
    Contributor

    I can not reproduce this issue on latest main & staging 9.5.20-0

    CleanShot.2026-10-26.at.20.43.52.1.mp4
  8. suneox commented on Oct 26, 2026

    @suneox
    Contributor

    I don't think this is a regression from #103359, that PR doesn't update DynamicWorkspaceEditTagsPage or DynamicWorkspaceViewTagsPage at all, so I think it's a flaky bug.

    CleanShot.2026-10-26.at.21.24.16.1.mp4

    @mitarachim Could you please retest and confirm whether it consistently reproduces, and whether the "Not here" page recovers on its own after a refresh? Thanks!

  9. 8 remaining items

  10. suneox commented on Oct 27, 2026

    @suneox
    Contributor

    @MelvinBot Analyze the flaky issue and provide a fix

  11. MelvinBot commented on Oct 27, 2026

    @MelvinBot
    Contributor

    ⚠️ Preliminary analysis (low confidence) — treat as a starting point, not a conclusion.

    This doesn't look flaky. The original tester reproduces it every time they rename the first list from the CSV ("Department"). The retest skipped that step.

    I think the backend returns the renamed list with a different orderWeight than the one in the URL, or stores it under a key that doesn't match its name. The view page finds the list by orderWeight and shows "Not here" when nothing matches: DynamicWorkspaceViewTagsPage.tsx:84-87 and :185-187. The App's own rename keeps orderWeight unchanged (Tag.ts:986-994), so the App can't create this state alone.

    Likely trigger: the CSV's first column ("Department") gets the same orderWeight as the existing NetSuite departments list. That would explain why only the first CSV list breaks.

    I couldn't verify this. I had no NetSuite-connected test account, and I couldn't read backend code or logs in this run.

    To confirm, an internal engineer should check the tester's policy:

    1. policyTags_<policyID> after the append: each list's key, name, and orderWeight. Does "Department" share an orderWeight with the NetSuite list?
    2. The RenamePolicyTaglist request (oldName, tagListIndex) and the Onyx data it returns.

    Fix direction:

    • If confirmed, the real fix is in the backend. Appended lists need unique orderWeights after the existing lists, and rename must keep orderWeight. That is outside the App repo.
    • App hardening only (it won't fix bad data):
      • In the view page, use the list object found by orderWeight directly instead of policyTags[name]. This covers a key that doesn't match name.
      • In the duplicate-name check, exclude the current list by name instead of by orderWeight (DynamicWorkspaceEditTagsPage.tsx:55).

    Next Steps: Reply with @MelvinBot <your feedback> to refine this analysis.


    view run

  12. added
    ExternalAdded to denote the issue can be worked on by a contributor
    on Oct 27, 2026
  13. melvin-bot commented on Oct 27, 2026

    @melvin-bot

    Current assignee @suneox is eligible for the External assigner, not assigning anyone new.

  14. changed the title [-]Tags - Not here page opens after editing custom tag name from uploaded CSV[/-] [+][$175] Tags - Not here page opens after editing custom tag name from uploaded CSV[/+] on Oct 27, 2026
  15. melvin-bot commented on Oct 27, 2026

    @melvin-bot
  16. Kabeer099 commented on Oct 27, 2026

    @Kabeer099

    Proposal

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

    When a workspace is connected to an accounting integration (such as NetSuite with Import > Departments > Import as Tag) and the admin uses More > Append custom tag list (indirectTagUploads beta) to upload an independent multi-level CSV (Department,Region,Third,Four), opening the first appended custom tag list (Department) and renaming its Custom tag name causes DynamicWorkspaceViewTagsPage to show the <NotFoundPage /> ("Hmm... it's not here") screen.

    What is the root cause of that problem?

    There are two interacting issues in how appended multi-level tag lists are imported, looked up by orderWeight, and renamed:

    1. Duplicate orderWeight collision and lookup mismatch in DynamicWorkspaceViewTagsPage.tsx and src/libs/PolicyUtils/tag.ts:

      • When ImportMultiLevelTags runs with appendToExistingLists: true (src/libs/actions/Policy/Tag.ts:955-962), the workspace keeps its existing accounting tag list (Departments at orderWeight: 0) alongside the newly uploaded CSV lists (Department, Region, Third, Four).
      • In src/pages/workspace/tags/DynamicWorkspaceViewTagsPage.tsx (lines 84–87):
        const currentTagListName = getTagListName(policyTags, orderWeight);
        const currentPolicyTag = policyTags?.[currentTagListName];
        and in src/libs/PolicyUtils/tag.ts (lines 27–33):
        function getTagListName(policyTagList: OnyxEntry<PolicyTagLists>, orderWeight: number): string {
            if (isEmptyObject(policyTagList)) {
                return '';
            }
        
            return Object.values(policyTagList).find((tag) => tag.orderWeight === orderWeight)?.name ?? '';
        }
      • Notice two problems here:
        • First, unlike getTagLists (line 44, which filters .filter((policyTagListValue) => policyTagListValue !== null)), getTagListName and getTagListByOrderWeight do not guard against null/falsy entries or key/name mismatches in policyTagList.
        • Second, when renamePolicyTagList (src/libs/actions/Policy/Tag.ts:981-1030) executes:
          value: {
              [newName]: {...oldPolicyTags, name: newName, pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, errors: null},
              [oldName]: null,
          }
          Deleting [oldName] (null) and inserting [newName] moves the renamed tag list entry to the end of the policyTags object key order, and when the RenamePolicyTagList backend command responds (or when another list shares the same orderWeight: 0 ahead of [newName] in Object.values(policyTags) / when the backend normalizes the appended list's orderWeight), getTagListName(policyTags, orderWeight) either resolves to the earlier list sharing orderWeight or returns '' when the orderWeight shifts, causing currentPolicyTag at DynamicWorkspaceViewTagsPage.tsx:185 (if (!currentPolicyTag) return <NotFoundPage />;) to evaluate to undefined and render <NotFoundPage />.
    2. Skipping ImportMultiLevelTagsSettingsPage on append never initializes isImportingIndependentMultiLevelTags (src/pages/workspace/tags/WorkspaceTagsPage.tsx:448-452):

      • In WorkspaceTagsPage.tsx (lines 449–450), navigateToAppendCustomTagList calls setImportedSpreadsheetIsImportingMultiLevelTags(true) and setImportedSpreadsheetIsAppendingToExistingLists(true), and in ImportMultiLevelTagsSettingsPage.tsx (line 163) the independent-tags toggle is hidden when isAppendingToExistingLists is true (/* Appended tag lists are always independent, so the dependent option isn't offered */). Ensure isIndependent: spreadsheet.isAppendingToExistingLists ? true : spreadsheet.isImportingIndependentMultiLevelTags is always true in importMultiLevelTags (src/libs/actions/Policy/Tag.ts:958).

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

    1. In src/libs/PolicyUtils/tag.ts (getTagListName and getTagListByOrderWeight):
      • Filter out nullish entries (Boolean) before calling .find((tag) => tag.orderWeight === orderWeight).
    2. In src/pages/workspace/tags/DynamicWorkspaceViewTagsPage.tsx and src/pages/workspace/tags/DynamicWorkspaceEditTagsPage.tsx:
      • Look up currentPolicyTag directly via getTagListByOrderWeight(policyTags, orderWeight) (or preserve the active tag list across renames when multiple lists exist / when orderWeight is updated by the server response) instead of doing a two-step getTagListName -> policyTags?.[currentTagListName] lookup, and if the renamed tag list's orderWeight changes on server sync while viewing DynamicWorkspaceViewTagsPage, keep resolving the renamed list (or update the route orderWeight param) so currentPolicyTag does not become undefined.
    3. In src/libs/actions/Policy/Tag.ts (renamePolicyTagList & importMultiLevelTags):
      • In renamePolicyTagList (line 991), ensure orderWeight: tagListIndex is explicitly preserved on [newName] in optimisticData, and in importMultiLevelTags (line 958), pass isIndependent: spreadsheet.isAppendingToExistingLists ? true : spreadsheet.isImportingIndependentMultiLevelTags.

    What alternative solutions did you explore? (Optional)

    Passing the tag list name in the route params of DYNAMIC_TAG_LIST_VIEW in addition to orderWeight was considered, but keeping orderWeight as the route param while making renamePolicyTagList and DynamicWorkspaceViewTagsPage resilient to key reordering and orderWeight collisions avoids changing all existing dynamic route callers.

  17. Enes2553 commented on Oct 28, 2026

    @Enes2553

    Proposal

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

    When a workspace is connected to NetSuite with Import > Departments > Tag enabled and the admin uses More > Append custom tag list (indirectTagUploads beta) to upload Independent.-.Multi.Level.tags.csv (Department,Region,Third,Four), opening the first uploaded custom tag list (Department) and renaming its Custom tag name causes DynamicWorkspaceViewTagsPage to open <NotFoundPage /> ("Hmm... it's not here").

    What is the root cause of that problem?

    This reproduces specifically when the uploaded CSV's first column (Department in Independent.-.Multi.Level.tags.csv) shares its name/key with the existing NetSuite Department tag list (which is why uploading a different CSV without a colliding Department column did not reproduce the issue in earlier retests):

    1. Two-step name-key lookup in DynamicWorkspaceViewTagsPage.tsx (lines 84-87):

      const currentTagListName = getTagListName(policyTags, orderWeight);
      const hasDependentTags = hasDependentTagsPolicyUtils(policy, policyTags);
      const isMultiLevelTags = isMultiLevelTagsPolicyUtils(policyTags);
      const currentPolicyTag = policyTags?.[currentTagListName];

      Instead of resolving currentPolicyTag directly by orderWeight, DynamicWorkspaceViewTagsPage resolves currentTagListName via getTagListName(policyTags, orderWeight) (src/libs/PolicyUtils/tag.ts:27-33) and then indexes policyTags?.[currentTagListName]. Whenever the Onyx dictionary key in policyTags differs from tag.name (or when two tag lists collide on the name "Department" / orderWeight), policyTags?.[currentTagListName] either points to the wrong list or evaluates to undefined, hitting if (!currentPolicyTag) { return <NotFoundPage />; } at DynamicWorkspaceViewTagsPage.tsx:185-187.

    2. Key-based lookup instead of orderWeight lookup in renamePolicyTagList (src/libs/actions/Policy/Tag.ts:981-1020):

      function renamePolicyTagList(policyID: string, policyTagListName: {oldName: string; newName: string}, policyTags: OnyxEntry<PolicyTagLists>, tagListIndex: number) {
          const newName = policyTagListName.newName;
          const oldName = policyTagListName.oldName;
          const oldPolicyTags = policyTags?.[oldName] ?? {};
          const onyxData: OnyxData<typeof ONYXKEYS.COLLECTION.POLICY_TAGS> = {
              optimisticData: [
                  {
                      onyxMethod: Onyx.METHOD.MERGE,
                      key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`,
                      value: {
                          [newName]: {...oldPolicyTags, name: newName, pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, errors: null},
                          [oldName]: null,
                      },
                  },
              ],
      • renamePolicyTagList looks up oldPolicyTags via policyTags?.[oldName] instead of locating the entry whose orderWeight === tagListIndex.
      • When the appended CSV list (Department) collides with the existing NetSuite Department list (or is stored under a disambiguated key / shares orderWeight), policyTags?.[oldName] either resolves to the NetSuite list (copying its orderWeight instead of tagListIndex) or falls back to {} (creating [newName] with orderWeight: undefined), while setting [oldName]: null deletes the "Department" key.
      • Furthermore, when [oldName]: null and [newName]: {...} are merged into policyTags, [newName] is appended to the end of Object.values(policyTags). If another list shares the same orderWeight (or if the backend RenamePolicyTaglist response normalizes the appended list's orderWeight), getTagListName(policyTags, orderWeight) no longer resolves to the renamed list, causing DynamicWorkspaceViewTagsPage to immediately render <NotFoundPage />.
    3. Missing null-guards in getTagListName, getTagListByOrderWeight, and getSortedTagKeys (src/libs/PolicyUtils/tag.ts:16-33, 173-185):
      Unlike getTagLists (line 44, which filters .filter((policyTagListValue) => policyTagListValue !== null)), getTagListName and getTagListByOrderWeight call Object.values(policyTagList).find((tag) => tag.orderWeight === orderWeight) without guarding against null entries left during Onyx merges.

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

    1. In src/libs/PolicyUtils/tag.ts (lines 16-33, 173-185):

      • Filter out nullish entries (Boolean(tag)) in getSortedTagKeys, getTagListName, and getTagListByOrderWeight, and add a helper findTagListEntryByOrderWeight(policyTagList: OnyxEntry<PolicyTagLists>, orderWeight: number) that returns [tagKey, tagList] for the matching orderWeight:
      function findTagListEntryByOrderWeight(policyTagList: OnyxEntry<PolicyTagLists>, orderWeight: number): [string, ValueOf<PolicyTagLists>] | undefined {
          if (isEmptyObject(policyTagList)) {
              return undefined;
          }
      
          return Object.entries(policyTagList).find((entry): entry is [string, ValueOf<PolicyTagLists>] => Boolean(entry[1]) && entry[1].orderWeight === orderWeight);
      }
    2. In src/pages/workspace/tags/DynamicWorkspaceViewTagsPage.tsx (lines 84-87):

      • Resolve currentPolicyTag directly from the entry matching orderWeight (with a fallback to the last resolved renamed tag list key while focused if the server normalizes orderWeight on rename) instead of doing policyTags?.[currentTagListName]:
      const matchedTagListEntry = findTagListEntryByOrderWeight(policyTags, orderWeight);
      const currentPolicyTag = matchedTagListEntry?.[1];
      const currentTagListName = currentPolicyTag?.name ?? '';
    3. In src/libs/actions/Policy/Tag.ts (renamePolicyTagList, lines 981-1020):

      • Resolve [oldKey, oldPolicyTags] using findTagListEntryByOrderWeight(policyTags, tagListIndex) (falling back to [oldName, policyTags?.[oldName]]), and explicitly set orderWeight: tagListIndex on [newName] in optimisticData:
      const matchedEntry = findTagListEntryByOrderWeight(policyTags, tagListIndex);
      const oldKey = matchedEntry?.[0] ?? oldName;
      const oldPolicyTags = matchedEntry?.[1] ?? policyTags?.[oldName] ?? {};
      const onyxData: OnyxData<typeof ONYXKEYS.COLLECTION.POLICY_TAGS> = {
          optimisticData: [
              {
                  onyxMethod: Onyx.METHOD.MERGE,
                  key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`,
                  value: {
                      [newName]: {...oldPolicyTags, name: newName, orderWeight: tagListIndex, pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, errors: null},
                      ...(oldKey !== newName ? {[oldKey]: null} : {}),
                  },
              },
          ],
          successData: [
              {
                  onyxMethod: Onyx.METHOD.MERGE,
                  key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`,
                  value: {
                      [newName]: {pendingAction: null},
                      ...(oldKey !== newName ? {[oldKey]: null} : {}),
                  },
              },
          ],
          failureData: [
              {
                  onyxMethod: Onyx.METHOD.MERGE,
                  key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`,
                  value: {
                      ...(oldKey !== newName ? {[newName]: null} : {}),
                      [oldKey]: {
                          ...oldPolicyTags,
                          pendingAction: null,
                          errors: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('workspace.tags.genericFailureMessage'),
                      },
                  },
              },
          ],
      };
    4. In src/pages/workspace/tags/WorkspaceTagsPage.tsx (line 328):

      • Use ${policyTagList.name}_${policyTagList.orderWeight} for keyForList in multi-level mode so two tag lists with the same display name (Department) never collide on list item keys.

    What alternative solutions did you explore? (Optional)

    • Navigating to tag lists by name instead of orderWeight: rejected because dynamic tag routes (DYNAMIC_TAG_LIST_VIEW / DYNAMIC_TAGS_EDIT) are keyed by :orderWeight across the entire app, and two lists can temporarily share the same display name (Department) right after appending a CSV. Resolving by orderWeight directly and preserving orderWeight: tagListIndex in renamePolicyTagList fixes the bug cleanly without changing route schemas.
  18. suneox commented on Oct 29, 2026

    @suneox
    Contributor

    I can reproduce this bug and will troubleshoot it soon

  19. suneox commented on Oct 29, 2026

    @suneox
    Contributor

    I looked into what happens after the import and after the rename.

    1. Data after appending the CSV

    The CSV's first column is named like the NetSuite list (Department). After the append, policyTags_<policyID> has two lists with the same name. The BE stores the new one under a different key:

    Onyx key name orderWeight Tags
    Department Department 1 16 (NetSuite, externalID: "Departments")
    Department_2 Department 2 6 (from the CSV)

    2. Why the rename ends on "Not here" (code at the time of the report)

    1. Opening the CSV list goes to /workspace-tag-list/2. The page converts orderWeight 2 to a name and looks the list up by that name, so it gets the NetSuite list (key Department) and shows its 16 tags: DynamicWorkspaceViewTagsPage.tsx#L84-L87, getTagListName
    2. "Custom tag name" opens the edit page with that list's orderWeight (1, not 2): DynamicWorkspaceViewTagsPage.tsx#L304
    3. Save sends RenamePolicyTaglist with oldName: "Department", tagListIndex: 1: DynamicWorkspaceEditTagsPage.tsx#L67. The optimistic data removes the key Department, i.e. the NetSuite list: Tag.ts#L984-L992
    4. The request returns 200, and the BE renames the NetSuite list (externalID: "Departments"). The CSV list is still named Department.
    5. Back on /workspace-tag-list/2, the name for orderWeight 2 is still Department, but the key Department no longer exists, so currentPolicyTag is undefined and the page shows Not Found: DynamicWorkspaceViewTagsPage.tsx#L185

    So the request succeeds, but it renames the wrong list, and the NetSuite list's name gets changed.

    3. Current main

    #105212 (merged for #105010) now finds tag lists by orderWeight and Onyx key on the App side: DynamicWorkspaceViewTagsPage.tsx#L84, renamePolicyTagList. With an equivalent local patch, the App opened the right list and sent oldName: "Dept CSV", tagListIndex: 2, but the BE still renamed the NetSuite list at index 1, then the page showed Not Found again. So RenamePolicyTaglist finds the list by oldName and ignores tagListIndex, which #105212 also notes.

    @yuwenmemon I suggest fixing this in the BE append: it shouldn't create a list whose name already exists. Either reject the import with an error, or rename the new list (its name too, not only the key). That matches the rule Classic's rename already has, stops duplicate lists from being created on both platforms, and keeps every name-based lookup in NewDot (tag pages, tag picker on expenses) unambiguous. What do you think?

    cc @trjExpensify

  20. trjExpensify commented on Oct 30, 2026

    @trjExpensify
    Contributor

    Either reject the import with an error

    This sounds good to me 👍

  21. yuwenmemon commented on Oct 30, 2026

    @yuwenmemon
    Contributor

    Well, technically, we do allow two tag lists with the same name. In fact, we added support for this here https://github.com/Expensify/Auth/pull/20714 about 7 months ago (stemming from https://github.com/Expensify/Expensify/issues/615983#issuecomment-4127986841). So blocking this wouldn't necessarily line up with how the feature is designed. We could start paying attention to the tagListIndex App sends to account for this... we're kind of ignoring it for the sake of the rename for now.

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.DailyKSv2EngineeringExternalAdded 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