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
Fix desktop profile switching when a profile has its own pooled gateway backend. The sidebar previously routed projects.tree to the primary/default gateway, so the selected profile could show no project folders or a partial tree from the wrong backend.
Root Cause
sharedPrimaryRoute() treated any connection descriptor with a profile field as a shared-primary route. Pooled profile descriptors also carry that field because it is needed to mint the profile-specific WebSocket URL. As a result, the renderer reused the default gateway instead of opening the selected profile's backend connection.
This change compares the selected profile's connection endpoint with the primary endpoint. Only an endpoint match is treated as shared; a distinct pooled endpoint opens and becomes the active profile socket.
Scope
Preserve the shared-global-remote behavior.
Route pooled profile project requests to their own gateway.
Add regression coverage for descriptors that carry profile on both shared and pooled routes.
This is complementary to #82823, which clears stale per-profile project cache state. This PR fixes the incorrect backend selection that produced the wrong project tree in the first place.
Validation
cd apps/desktop && npm run test -- gateway-shared-remote.test.ts
cd apps/desktop && npm run typecheck
Manual packaged-desktop verification on Windows: switching between novel-writer and regular_encoding loaded each profile's own project folders.
Comparing endpoints instead of the profile tag is the correct fix — pooled and shared descriptors both legitimately carry profile now. Observations:
apps/desktop/src/store/gateway.ts (sharedPrimaryRoute): Promise.all requires BOTH getConnection(profile) and getConnection() (primary) to resolve. If the primary-descriptor call rejects while the profile connection succeeds, the whole function returns false and the caller dials a second socket — resurrecting the exact "poisoned gateway" failure the comment describes. Consider Promise.allSettled (or per-call error handling) so a primary-descriptor failure doesn't force the wrong route.
connectionEndpoint compares endpoints as raw strings. A trailing slash, scheme case (https:// vs HTTPS://), or https:// vs wss:// difference between the two descriptors fails the match and causes a redundant second socket to be dialed. Normalizing (strip trailing /, lowercase the host) would make shared-primary detection more robust.
Minor: connectionEndpoint returns null for unrecognized descriptor shapes and sharedPrimaryRoute then falls through to the pooled path. Conservative, but a debug/warn log on the unrecognized shape would help diagnose misrouting when a new descriptor field replaces the existing ones.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
area/profilesMulti-profile isolation, HERMES_HOME scopingcomp/desktopElectron desktop app (apps/desktop/*)P2Medium — degraded but workaround existssweeper:risk-session-stateSweeper risk: may lose/corrupt/mis-associate session or context statetype/bugSomething isn't working
3 participants
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fix desktop profile switching when a profile has its own pooled gateway backend. The sidebar previously routed
projects.treeto the primary/default gateway, so the selected profile could show no project folders or a partial tree from the wrong backend.Root Cause
sharedPrimaryRoute()treated any connection descriptor with aprofilefield as a shared-primary route. Pooled profile descriptors also carry that field because it is needed to mint the profile-specific WebSocket URL. As a result, the renderer reused the default gateway instead of opening the selected profile's backend connection.This change compares the selected profile's connection endpoint with the primary endpoint. Only an endpoint match is treated as shared; a distinct pooled endpoint opens and becomes the active profile socket.
Scope
profileon both shared and pooled routes.This is complementary to #82823, which clears stale per-profile project cache state. This PR fixes the incorrect backend selection that produced the wrong project tree in the first place.
Validation
cd apps/desktop && npm run test -- gateway-shared-remote.test.tscd apps/desktop && npm run typechecknovel-writerandregular_encodingloaded each profile's own project folders.Closes #86107