You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug]: @ mention search closes on spaces in file, folder, and thread names #15156
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
In a workspace, create a folder Foreign Subsidiaries Motion Video containing Script Notes.md.
Open a new or existing thread and focus the composer.
Type @Foreign. The file/folder picker opens with matching results.
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.
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.
Activity
juliusmarminge commentedon Oct 3, 2026
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:
tokenStartForCursorinapps/web/src/composer-logic.ts.detectComposerTriggerinpackages/shared/src/composerTrigger.ts, called fromapps/mobile/src/features/threads/use-composer-command-menu.ts.So
@Foreign Subsidiariesbecomes the tokenSubsidiaries. It doesn't start with@, so the trigger is null. On web,composerMenuOpenisBoolean(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)inmatchComposerThreadItems. Path search trims and lowercases inWorkspaceEntries.search, then hands the string to fff, which treatsfoo baras two terms.useProjectPathSearchonly callstrim(), 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, withrangeStartpinned 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
useComposerTriggerStateonly sticks while the next candidate has the same kind andrangeStart. A space shouldn't produce a null candidate, becausesetTriggerclears 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.
omarbdri commentedon Oct 3, 2026
macroscope approved the changes!