{"record":{"id":"6dfed257dc03b4aa","repo":"RocketChat/Rocket.Chat","slug":"not-authorized","errorCode":"not-authorized","errorMessage":"Not authorized","messagePattern":"Not authorized","errorType":"exception","errorClass":"NotAuthorizedError","httpStatus":null,"severity":"error","filePath":"apps/meteor/client/views/room/hooks/useOpenRoom.ts","lineNumber":70,"sourceCode":"\t\treturn { rid: sub.rid };\n\t}, [reference, type, user?._id]);\n\n\tconst result = useQuery({\n\t\t// we need to add uid and username here because `user` is not loaded all at once (see UserProvider -> Meteor.user())\n\t\tqueryKey: roomsQueryKeys.roomReference(reference, type, user?._id, user?.username),\n\n\t\t// Render immediately from local cache when we already know the rid; queryFn still runs in\n\t\t// the background to revalidate permissions / fetch fresh room fields.\n\t\tplaceholderData: tryCacheShortcut,\n\n\t\tqueryFn: async (): Promise<{ rid: IRoom['_id'] }> => {\n\t\t\tconst cached = tryCacheShortcut();\n\t\t\tif (cached) {\n\t\t\t\tLegacyRoomManager.open({ typeName: type + reference, rid: cached.rid });\n\t\t\t\treturn cached;\n\t\t\t}\n\t\t\tif ((user && !user.username) || (!user && !allowAnonymousRead)) {\n\t\t\t\tthrow new NotAuthorizedError();\n\t\t\t}\n\n\t\t\tif (!reference || !type) {\n\t\t\t\tthrow new RoomNotFoundError(undefined, { type, reference });\n\t\t\t}\n\n\t\t\tlet roomData: IRoom;\n\t\t\ttry {\n\t\t\t\troomData = await getRoomByTypeAndName(type, reference);\n\t\t\t} catch (error) {\n\t\t\t\tconst errorCode = error && typeof error === 'object' && 'error' in error ? error.error : undefined;\n\n\t\t\t\t// \"No permission\" means the room exists but the user can't see it — surface the\n\t\t\t\t// not-found/no-access screen rather than retrying it as a transient failure.\n\t\t\t\tif (errorCode === 'error-no-permission') {\n\t\t\t\t\tthrow new RoomNotFoundError(undefined, { type, reference });\n\t\t\t\t}\n","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/client/views/room/hooks/useOpenRoom.ts#L52-L88","documentation":"Thrown as NotAuthorizedError (error id 'not-authorized') in the useOpenRoom queryFn. It fires when the current user object exists but has no username (account incompletely provisioned), or when there is no user at all and the Accounts_AllowAnonymousRead setting is false. The query is marked non-retryable for this error in the retry function.","triggerScenarios":"Authenticated session where Meteor.user() is loaded but the username field is missing; anonymous access disabled (Accounts_AllowAnonymousRead=false) and the visitor has no user; route opened before the user document finished syncing the username field.","commonSituations":"Freshly created account before username was set; LDAP/SAML login that did not map a username; guest/anonymous browsing with anonymous read turned off in admin settings.","solutions":["Ensure the logged-in user has a username set (admin > users, or via SET username flow) before opening rooms.","If anonymous browsing is intended, enable Accounts_AllowAnonymousRead in server settings.","Guard the route so it waits for the full user profile (including username) to load before invoking useOpenRoom."],"exampleFix":"// before\nif ((user && !user.username) || (!user && !allowAnonymousRead)) {\n  throw new NotAuthorizedError();\n}\n\n// after: wait for user profile to settle, then decide\nif (userLoading) return;\nif ((user && !user.username) || (!user && !allowAnonymousRead)) {\n  throw new NotAuthorizedError();\n}","handlingStrategy":"validation","validationCode":"// Ensure user is fully loaded with a username (or anonymous read allowed) before opening a room.\nif (!userLoading && ((user && !user.username) || (!user && !allowAnonymousRead))) {\n  // redirect to login or username-setup instead of running useOpenRoom\n}","typeGuard":"const isFullyProvisionedUser = (u: unknown): u is { _id: string; username: string } =>\n  typeof u === 'object' && u !== null &&\n  typeof (u as any)._id === 'string' &&\n  typeof (u as any).username === 'string' && (u as any).username.length > 0;","tryCatchPattern":"// NotAuthorizedError is unrecoverable; handle at the query error boundary.\nif (error instanceof NotAuthorizedError) {\n  return <NotAuthorizedScreen reason={error.details} />;\n}","preventionTips":["Wait for the full user profile (including username) before rendering room routes.","Verify Accounts_AllowAnonymousRead matches your anonymous-access policy.","For SSO flows, ensure the username mapping is configured so accounts provision with a username."],"tags":["client","auth","rooms","react-query","anonymous-access"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}