Skip to content

[Bug]: @ mention search closes on spaces in file, folder, and thread names #15156

Open

Description

@omarbdri

Before submitting

  • I searched existing issues and did not find an exact duplicate.
  • I included enough detail to reproduce the problem.

Area

apps/web and apps/desktop composer; the mobile picker has the same token-boundary logic.

Steps to reproduce

  1. In a workspace, create a folder Foreign Subsidiaries Motion Video containing Script Notes.md.
  2. Open a new or existing thread and focus the composer.
  3. Type @Foreign. The file/folder picker opens with matching results.
  4. Type a space, then continue with Subsidiaries Motion Video/Script Notes.

The same restriction prevents refining an @ thread search by a multi-word title.

Expected behavior

The picker stays open across spaces within an active search, filters the full query, and lets Enter accept the highlighted result. Escape still dismisses it; selecting a result ends the search.

Actual behavior

The picker closes immediately after the first space. Continuing to type cannot refine the query, so the user has to select the result from the first-word matches by scrolling or arrow navigation.

Version and environment

Source baseline: main at 31a9da179ed0763335f05681c577474aec5d2309 (web package 0.0.45).
macOS 27.0.1, Node 24.13.1. Reproduced in an isolated local T3 web dev app using the built-in Browser panel. The original report was from desktop. Native iOS/Android were not manually reproduced.

The search matchers already accept spaces; trigger detection stops at whitespace and loses the @ prefix.

Evidence

Before: the multi-word query has no picker

Before recording

Related reports

Impact and workaround

Minor bug affecting keyboard selection of multi-word names. Search only the first word, then use arrow keys or scroll to choose the desired result.

Activity

  1. juliusmarminge commented on Oct 3, 2026

    @juliusmarminge
    Member

    Note

    Grok responding on behalf of Julius.

    Triage

    Thanks @omarbdri for the clear repro and the before recording! I confirmed this one. An @ search closes at the first space, so you can't refine a multi-word file, folder, or thread name from the keyboard. Web and desktop share one detector, and mobile uses the same whitespace scan.

    This isn't a duplicate. #2571 / #2625 (closed, fix merged) covered a selected path with spaces getting split into a partial reference. Those mentions are now markdown links (serializeComposerFileLink) or quoted @"…" tokens (MENTION_TOKEN_REGEX). #291 / #936 (closed, fix merged) covered cursor offsets and insertion spacing. #10957 (closed) was about $ skill names with spaces. This report is about the query before anything is selected.

    What's going on

    Both detectors walk backward from the caret and stop at a space, newline, tab, or carriage return:

    • Web and desktop: tokenStartForCursor in apps/web/src/composer-logic.ts.
    • Mobile: the same walk in detectComposerTrigger in packages/shared/src/composerTrigger.ts, called from apps/mobile/src/features/threads/use-composer-command-menu.ts.

    So @Foreign Subsidiaries becomes the token Subsidiaries. It doesn't start with @, so the trigger is null. On web, composerMenuOpen is Boolean(composerTrigger), which means the menu closes and Enter no longer accepts the highlighted row.

    The matchers already handle queries with spaces. Thread titles use title.toLowerCase().includes(query) in matchComposerThreadItems. Path search trims and lowercases in WorkspaceEntries.search, then hands the string to fff, which treats foo bar as two terms. useProjectPathSearch only calls trim(), so a trailing space keeps the previous word's results while you type the next one. The full query just never reaches them once the space ends the trigger.

    Likely fix area

    Keep an @ search that's already open going across spaces, with rangeStart pinned to that @ so Enter replaces the whole multi-word query. Don't scan backward through prose and reopen an old @. A newline, a tab, or the terminal-context placeholder should still end the search, and so should deleting the @, selecting text, or accepting a result.

    Escape dismissal in useComposerTriggerState only sticks while the next candidate has the same kind and rangeStart. A space shouldn't produce a null candidate, because setTrigger clears the dismissal on null and would reopen the menu on the next character. $, /, and # should keep stopping at whitespace.

    Your open PR #15157 targets this, and it's going through the normal review flow. A maintainer will decide on the fix direction.

  2. added
    bugSomething is broken or behaving incorrectly.
    via-triageFiled through npx t3 triage
    on Oct 3, 2026
  3. omarbdri commented on Oct 3, 2026

    @omarbdri
    Author

    macroscope approved the changes!

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 or behaving incorrectly.via-triageFiled through npx t3 triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions