Fix intermittent "Channel access denied. User is not a participant" error#130
Open
bmiller59 wants to merge 2 commits into
Open
Fix intermittent "Channel access denied. User is not a participant" error#130bmiller59 wants to merge 2 commits into
bmiller59 wants to merge 2 commits into
Conversation
TokenManager stored tokens with no notion of which user they belonged to, so cross-tab TOKENS_REFRESHED broadcasts and cookie syncs were adopted unconditionally. A tab could authenticate as user B while building direct-channel names for user A, causing intermittent "User is not a participant" errors (most likely when two tabs create distinct guest sessions at once). Track an _ownerUserId in TokenManager: authoritative local writes (guest creation, login, cookie restore) establish the owner, while remote adoptions (broadcast, _syncFromCookie) are only accepted when their userId matches. Thread userId through Api.SetTokens and the three authoritative call sites, and document the behavior.
The test grabbed the last message:new handler (.at(-1)), which collided with the Transcript sidebar's listener. Invoke all registered handlers to faithfully simulate the socket broadcast so the assistant page's handler runs.
|
Deployment failed with the following error: View Documentation: https://vercel.com/docs/two-factor-authentication |
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
What is in this PR?
Fixes an intermittent "Channel access denied. User is not a participant" error caused by
TokenManageradopting tokens that belong to a different user. During cold-start races (e.g. two tabs creating guest sessions simultaneously, or a cookie sync overwriting freshly-issued tokens),SessionManager.userIdcould diverge from the user the tokens were actually minted for, so channel names likedirect-${userId}-${agentId}were built for a user the socket token didn't authorize.The fix makes
TokenManageridentity-aware: it tracks the user that owns the current tokens and rejects cross-tab broadcasts and cookie-sync tokens that belong to a different user.Changes in the codebase
utils/TokenManager.ts: Added_ownerUserIdto track the user owning the current tokens.setTokens(tokens, { broadcast?, userId? })now records the owner on authoritative writes and includesuserIdinTOKENS_REFRESHEDbroadcasts. Added guards in_handleTabMessage(adopt a broadcast only whenmessage.userId === _ownerUserId) and_syncFromCookie(ignore cookie tokens whoseuserIddiffers from the current owner, triggering a refresh instead).clearTokens()resets the owner.utils/Helpers.ts:Api.SetTokens(...)takes an optionaluserIdand forwards it throughsetTokensFromStrings.utils/SessionManager.ts/pages/login.tsx: ThreaduserIdthrough the three authoritative token-write call sites (cookie restore, guest create, login).__tests__/utils/TokenManager.test.ts/SessionManager.test.ts: Updated for the newsetTokenssignature; added coverage for cross-user broadcast/cookie rejection and authoritative owner updates.__tests__/pages/assistant.test.tsx: Fixed a pre-existing failing test (displays real-time messages from any agent direct channel). It grabbed.at(-1)of themessage:newlisteners, which collided with theTranscriptsidebar's own listener; now it dispatchesmessage:newto all registered handlers, faithfully simulating a socket broadcast.SESSION_AND_TOKEN_SYSTEM.md: Documented token identity ownership, updated the refresh-flow diagrams/pseudocode, the two-tab race scenario, console-log reference, and added a "Channel access denied" pitfall entry.Documentation and automated testing
Did you:
setTokens/SetTokenschanges are backward compatible via optional params)SESSION_AND_TOKEN_SYSTEM.md)content/whatsNew.tsfor new features? (n/a — internal bug fix)Testing this PR
Additional information
Known follow-up (out of scope): the gap-reconnect re-fetch in
pages/assistant.tsx(~line 611) does a fullsetAssistantMessagesreplace and could drop a real-time message that arrives mid-fetch — worth hardening to a merge later.