{"record":{"id":"64c78c8bb62fabe0","repo":"RocketChat/Rocket.Chat","slug":"error-unauthorized","errorCode":"error-unauthorized","errorMessage":"Users must have a username","messagePattern":"Users must have a username","errorType":"exception","errorClass":"Meteor.Error","httpStatus":401,"severity":"error","filePath":"apps/meteor/server/api/v1/middlewares/authenticationHono.ts","lineNumber":42,"sourceCode":"\t\tconst user = await api.authenticatedRoute(convertHonoContextToApiActionContext(c, { logger: options.logger }));\n\t\tconst shouldPreventAnonymousRead = !user && options.authOrAnonRequired && !settings.get('Accounts_AllowAnonymousRead');\n\t\tconst shouldPreventUserRead = !user && options.authRequired;\n\n\t\tif (shouldPreventAnonymousRead || shouldPreventUserRead) {\n\t\t\tconst result = api.unauthorized('You must be logged in to do this.');\n\t\t\t// TODO: MAJOR\n\t\t\tif (!applyBreakingChanges) {\n\t\t\t\tObject.assign(result.body, {\n\t\t\t\t\tstatus: 'error',\n\t\t\t\t\tmessage: 'You must be logged in to do this.',\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn c.json(result.body, result.statusCode);\n\t\t}\n\n\t\tif (user && !options.userWithoutUsername && !isUserWithUsername(user)) {\n\t\t\tthrow new Meteor.Error('error-unauthorized', 'Users must have a username');\n\t\t}\n\n\t\tc.set('user', user);\n\t\treturn next();\n\t};\n}\n","sourceCodeStart":24,"sourceCodeEnd":49,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/server/api/v1/middlewares/authenticationHono.ts#L24-L49","documentation":"Thrown by the Hono authentication middleware when a user object is resolved by authenticatedRoute() but the user has no username field (isUserWithUsername returns false). This blocks authenticated-but-usernameless accounts from accessing routes that don't explicitly set userWithoutUsername: true. The check runs after auth/anonymous gating, so the user identity is known — it is the username that is missing.","triggerScenarios":"An authenticated request where the user account exists and is valid but the username property is undefined. This can happen with certain OAuth/SAML accounts that did not complete username assignment, bot accounts created without a username, or users in a partially-migrated state.","commonSituations":"OAuth provider (Google, GitHub, etc.) returned no username and the account registration flow was interrupted; a bot or integration token was created programmatically without setting username; data migration from another platform left some users without usernames; the username was set to null by a cleanup script.","solutions":["Ensure the user account has a username assigned — via admin user management or the user completing their profile setup.","If the endpoint legitimately serves users without usernames (e.g., method.call routes that already set userWithoutUsername: true), add userWithoutUsername: true to the route's options.","For OAuth/SAML users, ensure the username mapping is configured in the OAuth/SAML settings."],"exampleFix":"// before (route definition without the flag)\nAPI.v1.get('my-endpoint', { authRequired: true }, action);\n// after (allow usernameless users if the endpoint supports it)\nAPI.v1.get('my-endpoint', { authRequired: true, userWithoutUsername: true }, action);","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"// Type guard to verify a user object has a username before making API calls\nimport type { IUser } from '@rocket.chat/core-typings';\n\nfunction userHasUsername(user: IUser | null | undefined): user is IUser & { username: string } {\n  return !!user && typeof user.username === 'string' && user.username.length > 0;\n}\n\n// Usage before calling an endpoint that requires a username\nif (!userHasUsername(currentUser)) {\n  console.warn('Current user has no username — this endpoint will reject the request.');\n}","tryCatchPattern":"try {\n  await callApiEndpoint();\n} catch (e) {\n  if (e.error === 'error-unauthorized' && e.reason?.includes('username')) {\n    console.error('User account has no username. Complete profile setup or contact admin.');\n    return;\n  }\n  throw e;\n}","preventionTips":["Ensure all user accounts (including OAuth/SAML/bots) have a username assigned during provisioning.","For routes that legitimately serve usernameless users, set userWithoutUsername: true in route options.","Run a periodic audit query to find users with null/undefined usernames."],"tags":["authentication","middleware","hono","username"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}