{"record":{"id":"3243da98fc04471c","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-user-3243da","errorCode":"error-invalid-user","errorMessage":"Invalid user","messagePattern":"Invalid user","errorType":"error_code","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/lib/bot-helpers/index.ts","lineNumber":83,"sourceCode":"\n\tasync addUserToRole(userName: string, roleId: string, userId: string): Promise<void> {\n\t\tawait addUserToRole(userId, roleId, userName);\n\t}\n\n\tasync removeUserFromRole(userName: string, roleId: string, userId: string): Promise<void> {\n\t\tawait removeUserFromRole(userId, roleId, userName);\n\t}\n\n\tasync addUserToRoom(userName: string, room: string): Promise<void> {\n\t\tconst foundRoom = await Rooms.findOneByIdOrName(room);\n\n\t\tif (!foundRoom) {\n\t\t\tthrow new Meteor.Error('invalid-channel');\n\t\t}\n\n\t\tconst userId = Meteor.userId();\n\t\tif (!userId) {\n\t\t\tthrow new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'addUserToRoom' });\n\t\t}\n\t\tawait addUsersToRoomMethod(userId, {\n\t\t\trid: foundRoom._id,\n\t\t\tusers: [userName],\n\t\t});\n\t}\n\n\tasync removeUserFromRoom(userName: string, room: string) {\n\t\tconst foundRoom = await Rooms.findOneByIdOrName(room);\n\n\t\tif (!foundRoom) {\n\t\t\tthrow new Meteor.Error('invalid-channel');\n\t\t}\n\t\tconst userId = Meteor.userId();\n\t\tif (!userId) {\n\t\t\tthrow new Meteor.Error('error-invalid-user', 'Invalid user');\n\t\t}\n\t\tawait removeUserFromRoomMethod(userId, { rid: foundRoom._id, username: userName });","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/lib/bot-helpers/index.ts#L65-L101","documentation":"Inside BotHelpers.addUserToRoom, Meteor.userId() returned null - the helper is executing without an authenticated user context. The botRequest DDP method authenticates the bot user before dispatching, so in practice this fires when the helper path is invoked from server code outside a user-bound method context, or when the session's user is lost across an await.","triggerScenarios":"Calling botHelpers.addUserToRoom from a cron job, app startup, or server fiber without a Meteor user; a long-running await resuming after the session was invalidated; test code invoking the helper directly.","commonSituations":"Refactors moving bot calls out of the authenticated request path; logout racing an in-flight bot request.","solutions":["Invoke the helper through the authenticated 'botRequest' DDP method so a user context exists","Thread the userId explicitly through your server code instead of relying on Meteor.userId()","Re-establish the bot's session (re-login) before retrying"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// server-side, before invoking the helper path:\nconst uid = Meteor.userId();\nif (!uid) {\n  // no authenticated user context - route the call through 'botRequest' instead\n}","typeGuard":null,"tryCatchPattern":"try {\n  await call('botRequest', 'addUserToRoom', username, room);\n} catch (e) {\n  if (e instanceof Meteor.Error && e.error === 'error-invalid-user') {\n    // session lost - re-authenticate the bot user and retry\n  } else {\n    throw e;\n  }\n}","preventionTips":["Invoke bot helpers only through the authenticated botRequest method","Thread userId explicitly through server code instead of relying on Meteor.userId()","Re-login the bot when sessions are invalidated (deployments, restarts)"],"tags":["rocket-chat","bots","authentication","meteor-methods","user-context"],"backgroundTag":"unauthenticated-request","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}