Skip to content

[Due for payment 2026-10-20] [$175] Click on FAB > New chat, search "Me" not display self DM in result list #102648

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.97-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: #102362
Email or phone of affected tester (no customers): lekima20+633509@gmail.com
Issue reported by: Applause Internal Team
Bug source: Pull Request QA execution
Device used: Win 11/Chrome
App Component: Money Requests

Action Performed:

  1. Open https://staging.new.expensify.com
  2. Click on search icon
  3. On search box, search "Me" > Observe the self email in the result list
  4. Close the search
  5. Click on + button > Start chat
  6. On search box, search "Me"

Expected Result:

Self DM should display in the result list

Actual Result:

"No result founds" is displayed

Workaround:

Unknown

Platforms:

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

Screenshots/Videos

Bug7273131_1790743782237.Recording__2521.mp4

View all open jobs on GitHub

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

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

Activity

  1. added
    BugSomething is broken. Auto assigns a BugZero manager.
    on Sep 30, 2026
  2. applause-bot commented on Sep 30, 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/ac792528c32eed67c2cd884a4ade7b7c7276111073724b29fdccb5cd8bb04833

  3. MelvinBot commented on Sep 30, 2026

    @MelvinBot
    Contributor

    Proposal

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

    In FAB > Start chat, searching "Me" shows "No results found" instead of the self DM.

    What is the root cause of that problem?

    The localized "You"/"Me" search terms are only added to the current user's contact row. They are never added to the self DM report row.

    • The main Search router passes includeCurrentUser: true, so it keeps your contact row. That row matches "Me" through getCurrentUserSearchTerms. See SearchAutocompleteList.tsx:273 and searchMatchUtils.ts:25-27.
    • New chat does not pass includeCurrentUser, so your contact row is excluded (index.ts:2402). The self DM is the only row that represents you.
    • The self DM is matched by doesReportMatchSearchTerms and its fallback filterReports. Both only check title, login, and room/thread/group fields. Neither adds "You"/"Me" for self DMs (index.ts:2845, index.ts:2888-2905).

    This problem existed before Remove TranslateLocal in src/libs/OptionsListUtils/searchMatchUtils.ts, which is why production also shows it. That PR only changed how translate is passed in.

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

    Make both report matchers in src/libs/OptionsListUtils/index.ts treat a self DM like the current user:

    1. Add a translate parameter to doesReportMatchSearchTerms. When report.isSelfDM is true, append translate('common.you') and translate('common.me') to its search text. Pass translate from getValidOptions (index.ts:2255).
    2. Make the same change in filterReports, and update its callers. This keeps the quick check a superset of filterReports, as the code comment requires. It also fixes the Search "In" filter, which uses filterReports.
    3. Add unit tests. Searching "me" with includeSelfDM: true should return the self DM, in both getValidOptions and filterAndOrderOptions.

    What alternative solutions did you explore? (Optional)

    You could pass includeCurrentUser: true in New chat. I don't recommend it. It would add a second row for yourself with an "Add to group" button, next to the self DM.

    Investigation details
    • In New chat, the self DM already appears when the search is empty, when you search your own email, and when you search "You" in English, because its title is "Name (you)". Only "Me", and "You"/"Me" in other languages, fail. The exception is when your name or email happens to contain the term.
    • The server search (searchInServer) only loads more data into Onyx. The same client-side filter still runs over it, so it does not change the result.
    • The participant picker (ParticipantSearchResults.tsx) uses the same path without includeCurrentUser. It likely has the same problem, and this fix covers it too.
    • No existing unit tests search "me" or "you".

    Next Steps for Contributor+ team:
    To accept: @MelvinBot implement [this](https://github.com/Expensify/App/issues/102648) 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 30, 2026
  5. melvin-bot commented on Sep 30, 2026

    @melvin-bot

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

  6. changed the title [-]Click on FAB > New chat, search "Me" not display self DM in result list[/-] [+][$175] Click on FAB > New chat, search "Me" not display self DM in result list[/+] on Sep 30, 2026
  7. melvin-bot commented on Sep 30, 2026

    @melvin-bot
  8. amar-sheikh commented on Sep 30, 2026

    @amar-sheikh

    Proposal

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

    In FAB > Start chat, searching "Me" shows "No results found" instead of your self DM, even though the same term correctly finds you in the general search box.

    What is the root cause of that problem?

    The localized "You"/"Me" search terms are only attached to the current user's contact row, never to the self DM report row itself.

    getCurrentUserSearchTerms is what makes "You"/"Me" searchable, and it only runs against your personal-details contact entry:

    /**
    * Includes localized "You"/"Me" so the current user is findable
    * by those terms in any supported language.
    *
    * @returns Raw (not lowercased) terms: display text, login,
    * login with dots stripped before @, and translated "You"/"Me".
    */
    function getCurrentUserSearchTerms(item: PersonalDetailFilterRankFields, translate: LocalizedTranslate) {
    return [item.text ?? item.displayName ?? '', item.login ?? '', item.login?.replace(CONST.EMAIL_SEARCH_REGEX, '') ?? '', translate('common.you'), translate('common.me')];
    }

    That contact row only exists when includeCurrentUser: true is passed in, which the general search box does but "Start chat" does not — includeCurrentUser defaults to false, and when it's falsy your own login is explicitly excluded from the contacts collection:

    let personalDetailLoginsToExclude = loginsToExcludeFromSuggestions;
    if (currentUserEmail) {
    personalDetailLoginsToExclude = {
    ...loginsToExcludeFromSuggestions,
    [currentUserEmail]: !config.includeCurrentUser,
    };
    }

    includeCurrentUser = false,

    So in "Start chat", the self DM is the only row left representing you, and it's matched by filterReports / doesReportMatchSearchTerms. Neither of these ever looks at isSelfDM or adds "You"/"Me" — they only check title, login, and room/thread/group-specific fields:

    function filterReports(reports: SearchOptionData[], searchTerms: string[]): SearchOptionData[] {
    const normalizedSearchTerms = searchTerms.map((term) => StringUtils.normalizeForMatch(term));
    // We search eventually for multiple whitespace separated search terms.
    // We start with the search term at the end, and then narrow down those filtered search results with the next search term.
    // We repeat (reduce) this until all search terms have been used:
    const filteredReports = normalizedSearchTerms.reduceRight(
    (items, term) =>
    filterArrayByMatch(items, term, (item) => {
    const values: string[] = [];
    if (item.text) {
    values.push(StringUtils.normalizeForMatch(item.text));
    values.push(StringUtils.normalizeForMatch(item.text).replaceAll(/['-]/g, ''));
    }
    if (item.login) {
    values.push(StringUtils.normalizeForMatch(item.login));
    values.push(StringUtils.normalizeForMatch(item.login.replace(CONST.EMAIL_SEARCH_REGEX, '')));
    }
    if (item.isThread) {
    if (item.alternateText) {
    values.push(StringUtils.normalizeForMatch(item.alternateText));
    }
    } else if (!!item.isChatRoom || !!item.isPolicyExpenseChat) {
    if (item.subtitle) {
    values.push(StringUtils.normalizeForMatch(item.subtitle));
    }
    }
    return uniqFast(values);
    }),
    // We start from all unfiltered reports:
    reports,
    );
    return filteredReports;
    }

    /**
    * Whether a report matches every search term. Keep the cheap substring check a superset of filterReports(): that
    * canonical matcher handles apostrophes, hyphens, zero-width characters, diacritics, and emails searched without
    * their dots, and only runs when the cheap check misses. Narrowing the cheap check silently drops matches.
    */
    function doesReportMatchSearchTerms(report: SearchOption<Report>, searchTerms: string[]): boolean {
    const normalizeSearchText = (value: string) => deburr(StringUtils.normalizeForMatch(value).toLocaleLowerCase());
    const normalizedSearchTerms = searchTerms.map(normalizeSearchText);
    let searchText = `${report.text ?? ''}${report.login ?? ''}`;
    if (report.isThread) {
    searchText += report.alternateText ?? '';
    } else if (report.isChatRoom) {
    searchText += report.subtitle ?? '';
    } else if (report.isPolicyExpenseChat) {
    searchText += `${report.subtitle ?? ''}${report.item.policyName ?? ''}`;
    } else if (report.item.chatType === CONST.REPORT.CHAT_TYPE.GROUP) {
    const participantsSearchText = report.participantsList?.map((participant) => [participant.displayName, participant.login].filter(Boolean).join(' ')).join(' ') ?? '';
    searchText += participantsSearchText;
    }
    searchText = normalizeSearchText(searchText);
    return normalizedSearchTerms.every((term) => searchText.includes(term)) || filterReports([report], normalizedSearchTerms).length > 0;
    }

    That's why "Me" (and "You" in any non-English locale, since the self DM's title only literally contains the English word "you" in parentheses) returns nothing for the self DM specifically, while everything else about it — searching your name, your email, or leaving the box empty — still works.

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

    Teach both report matchers in src/libs/OptionsListUtils/index.ts to treat a self DM the same way getCurrentUserSearchTerms treats the current user's contact row:

    1. In filterReports, when building the searchable values for an item, also push the translated common.you / common.me strings whenever item.isSelfDM is true.
    2. In doesReportMatchSearchTerms, do the same for report.isSelfDM when building searchText, so the cheap check stays a superset of filterReports (the function's own comment requires this).
    3. Both functions currently don't receive a translate function — thread it through from their callers (ultimately getValidOptions), the same way getCurrentUserSearchTerms already receives it.
    4. Add a unit test: with a self DM present and includeSelfDM: true, searching "me" (and "you") should return it, for both getValidOptions and the filterReports-based "Search > In" filter, since filterReports is shared by both paths.

    What alternative solutions did you explore? (Optional)

    Passing includeCurrentUser: true into "Start chat" would also make "Me" match, but it adds a second, separate row for yourself (with its own "Add to group" affordance) next to the self DM row, which isn't the expected single-row result shown in the issue's video. Fixing the self DM's own search terms instead keeps exactly one row for "you," matching the expected result.

  9. parasharrajat commented on Sep 30, 2026

    @parasharrajat
    Member

    @MelvinBot implement this #102648 (comment)

    🎀 👀 🎀 C+ reviewed

  10. parasharrajat commented on Sep 30, 2026

    @parasharrajat
    Member

    oops wrong comment.

  11. MelvinBot commented on Sep 30, 2026

    @MelvinBot
    Contributor

    🤖 Draft PR created: Match the self DM by the localized You/Me in report search
    Please mark it as "Ready for review" when it is ready for review.

    It implements this proposal. filterReports and doesReportMatchSearchTerms now match self DMs against the localized "You"/"Me", so Start chat finds the self DM when you search "Me". Typecheck, lint, formatting, spelling, and the related Jest suites pass, including new unit tests for this case. I did not test it manually in the app.


    view run

  12. MelvinBot commented on Sep 30, 2026

    @MelvinBot
    Contributor

    🤖 I didn't create a new PR for this request. You marked it as the wrong comment, and Match the self DM by the localized You/Me in report search already implements this proposal as a draft.

    If you want my proposal implemented instead, reply @MelvinBot implement this and say so.


    view run

  13. 20 remaining items

  14. melvin-bot commented on Oct 19, 2026

    @melvin-bot

    Triggered auto assignment to @mallenexpensify (Awaiting Payment)

  15. melvin-bot commented on Oct 19, 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
  16. mallenexpensify commented on Oct 20, 2026

    @mallenexpensify
    Contributor

    Payment Summary

    Contributor+: @parasharrajat due $175 via NewDot

    @parasharrajat plz complete the Contributor+ checklist and tag me in a post once you have. Thx

  17. melvin-bot commented on Oct 23, 2026

    @melvin-bot

    @mallenexpensify Uh oh! This issue is overdue by 2 days. Don't forget to update your issues!

  18. mallenexpensify commented on Oct 23, 2026

    @mallenexpensify
    Contributor

    @parasharrajat plz complete the Contributor+ checklist and tag me in a post once you have. Thx

  19. parasharrajat commented on Oct 26, 2026

    @parasharrajat
    Member

    BugZero Checklist:

    • [Contributor] The offending PR and associated issue have been commented on, pointing out the bug it caused and why, so the author and reviewers can learn from the mistake.

      Link to the comment on the PR: New Feature
      Link to the comment on the Issue: New Feature

    • [Contributor] If the regression was CRITICAL (e.g. interrupts a core flow) A discussion in #expensify-open-source has been started about whether any other steps should be taken (e.g. updating the PR review checklist) in order to catch this type of bug sooner.

      Link to discussion:

    • [Contributor] If it was decided to create a regression test for the bug, please propose the regression test steps using the template below to ensure the same bug will not reach production again.

    • [BugZero Assignee] Create a GH issue for creating/updating the regression test once above steps have been agreed upon.

      Link to issue: https://github.com/Expensify/Expensify/issues/696148

    Regression Test Proposal

    Precondition:

    Test:

    1. Open staging.new.expensify.com
    2. Click on search icon
    3. On search box, search "Me" > Observe the self email in the result list
    4. Close the search
    5. Click on + button > Start chat
    6. On search box, search "Me".
    7. Verify that selfDM chat is shown in the list.

    Do we agree 👍 or 👎

    Zapier Logs Run ID: 00040eee-7b0e-a7a2-1fe3-8bd9904eadc4
  20. parasharrajat commented on Oct 26, 2026

    @parasharrajat
    Member
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