Skip to content

fix(desktop): keep all sessions when ALL-profiles scope is active with a single profile - #84313

Closed
andyst-dev wants to merge 1 commit into
NousResearch:mainfrom
andyst-dev:fix/sidebar-all-profiles-single-profile
Closed

fix(desktop): keep all sessions when ALL-profiles scope is active with a single profile#84313
andyst-dev wants to merge 1 commit into
NousResearch:mainfrom
andyst-dev:fix/sidebar-all-profiles-single-profile

Conversation

@andyst-dev

Copy link
Copy Markdown
Contributor

Fixes #84305

Problem

In the desktop app, choosing Grouping → Profile in the sidebar Filters menu
persists $showAllProfiles, which drives $profileScope to ALL_PROFILES even
when there is only a single profile (default). The sidebar then computed
showAllProfiles = multiProfile && profileScope === ALL_PROFILES, which is
false for a single profile — so the flat sessions list was filtered against
the __all__ sentinel (normalizeProfileKey(s.profile) === '__all__'), matching
nothing. Result: the sidebar's recents section rendered the empty state
("no sessions") even though the backend returned all rows for recents_profile=all.
Clicking the default chip (which leaves ALL scope) instantly restored the list.

The grouped rendering is intentionally gated on multiProfile (to avoid stranding
single-profile users in a grouped view with no rail), but the data scoping must
still fan every profile in when the scope is ALL.

Fix

Extract the scope selector into a pure helper, selectVisibleSessions(sessions, profileScope),
that treats ALL_PROFILES as "include everything" regardless of the multi-profile
grouping gate, and filters by concrete profile otherwise. scopedSessions now uses it,
so a single-profile user in the ALL scope sees their rows (as a flat list — the grouped
view stays off because it is still gated on multiProfile).

Tests

Added apps/desktop/src/app/chat/sidebar/session-scope.test.ts (6 tests) covering:

  • ALL scope returns every session
  • the regression: ALL scope with sessions owned by a single profile is not emptied
  • concrete scope returns only the matching profile
  • session profile normalization before matching
  • null profile treated as default
  • empty result when no session matches a concrete scope

Verified: new + existing sidebar tests pass (125 tests, 14 files), tsc --noEmit clean,
eslint clean.

@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have comp/desktop Electron desktop app (apps/desktop/*) area/sessions Session lifecycle, resume, persistence, history area/profiles Multi-profile isolation, HERMES_HOME scoping sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state labels Aug 12, 2026
@Enough1122

Copy link
Copy Markdown
Contributor

AI code review — automated review for reference, author can ignore or act on any point.

fix(desktop): keep all sessions when ALL-profiles scope is active with a single profile

  1. showAllProfiles was dropped from the useMemo dependency array (apps/desktop/src/app/chat/sidebar/index.tsx:448). The new selector treats profileScope as the single source of truth, and session-scope.ts documents the $showAllProfiles$profileScope coupling — but if any path updates $showAllProfiles without $profileScope following (or vice versa), the recents list goes stale. Verify the two stores are always updated in lockstep (ideally profileScope derives from showAllProfiles in one place), otherwise keep showAllProfiles in the deps.
  2. selectVisibleSessions normalizes the session side (normalizeProfileKey(s.profile)) but compares against the raw profileScope argument (session-scope.ts:135). A concrete scope carrying stray whitespace (' work ') would match nothing while the session side is trimmed. Normalize both sides for symmetry — the tests only cover a dirty session-side value.
  3. In the ALL_PROFILES branch the selector returns the caller's array reference unchanged (session-scope.ts:131). Harmless for the memoized call site today, but any future caller that filters or mutates the result would mutate the source pool. A return [...sessions] would make the contract safer; minor.
  4. The extracted selector is cleanly factored and the six tests pin the sentinel behavior, the single-profile ALL-scope regression, normalization, and null-profile handling — good coverage of the exact bug described.

…h a single profile

Grouping -> Profile persists $showAllProfiles, which drives $profileScope to
ALL_PROFILES even when there is only one profile. The sidebar scoped that as
showAllProfiles = multiProfile && scope === ALL, which is false for a single
profile, so the flat list filtered against the __all__ sentinel and matched
nothing — rendering the sidebar empty even though the backend served every row.

Extract the scope selector into a pure helper that treats ALL_PROFILES as
'include everything' regardless of the multi-profile grouping gate, and use it
for the scoped sessions list. Single-profile users in the ALL scope now see
their rows (as a flat list, since the grouped view stays gated on multiProfile).
@andyst-dev

Copy link
Copy Markdown
Contributor Author

Rebased onto latest upstream main — resolved the import conflict with the session-index/session-scope split.

@andyst-dev andyst-dev closed this Aug 17, 2026
@andyst-dev andyst-dev reopened this Aug 17, 2026
@andyst-dev
andyst-dev force-pushed the fix/sidebar-all-profiles-single-profile branch from f54c25f to 380cd9c Compare August 17, 2026 08:24
@Manu606972

Copy link
Copy Markdown

still hitting this after the Aug 18 update

@OutThisLife

Copy link
Copy Markdown
Collaborator

Superseded by #89817.

That salvage keeps the ALL-scope include-everything rule, rebased onto current main, and:

  • uses the existing filterSessionsByProfileScope helper (cron and messaging already did)
  • drops the new session-scope.ts / selectVisibleSessions duplicate
  • adds the single-profile ALL-scope regression on that helper

You're credited via Co-authored-by. Thanks for pinning the Grouping > Profile empty-list path.

OutThisLife added a commit that referenced this pull request Aug 19, 2026
…cope

fix(desktop): keep recents when ALL-profiles scope has one profile (supersedes #84313)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/profiles Multi-profile isolation, HERMES_HOME scoping area/sessions Session lifecycle, resume, persistence, history comp/desktop Electron desktop app (apps/desktop/*) P3 Low — cosmetic, nice to have sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Desktop sidebar empty in all-profiles view (Grouping = Profile) with single profile — backend serves rows fine

5 participants