{"record":{"id":"c24169514ab4a4b3","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-room-c24169","errorCode":"error-invalid-room","errorMessage":"Invalid room","messagePattern":"Invalid room","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/meteor-methods/rooms/addAllUserToRoom.ts","lineNumber":50,"sourceCode":"\t}\n\n\tconst userFilter: {\n\t\tactive?: boolean;\n\t} = {};\n\tif (activeUsersOnly === true) {\n\t\tuserFilter.active = true;\n\t}\n\n\tconst users = await Users.find(userFilter).toArray();\n\tif (users.length > settings.get<number>('API_User_Limit')) {\n\t\tthrow new Meteor.Error('error-user-limit-exceeded', 'User Limit Exceeded', {\n\t\t\tmethod: 'addAllToRoom',\n\t\t});\n\t}\n\n\tconst room = await Rooms.findOneById(rid);\n\tif (!room) {\n\t\tthrow new Meteor.Error('error-invalid-room', 'Invalid room', {\n\t\t\tmethod: 'addAllToRoom',\n\t\t});\n\t}\n\n\tawait beforeAddUserToRoom(\n\t\tusers.map((u) => u.username!),\n\t\troom,\n\t);\n\n\tconst now = new Date();\n\tfor await (const user of users) {\n\t\tconst subscription = await Subscriptions.findOneByRoomIdAndUserId(rid, user._id);\n\t\tif (subscription != null) {\n\t\t\tcontinue;\n\t\t}\n\t\tawait callbacks.run('beforeJoinRoom', user, room);\n\t\tconst autoTranslateConfig = getSubscriptionAutotranslateDefaultConfig(user);\n\t\tconst { insertedId } = await Subscriptions.createWithRoomAndUser(room, user, {","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/meteor-methods/rooms/addAllUserToRoom.ts#L32-L68","documentation":"Inside addAllUserToRoomFn, Rooms.findOneById(rid) returned null, so the room id passed to addAllUserToRoom does not exist. Ordering matters: the permission and user-limit checks run first, then this lookup, then beforeAddUserToRoom and the per-user join loop - so a caller hitting this error already passed 403 and the limit check.","triggerScenarios":"Passing a wrong or truncated rid; the room was deleted (or team channel removed) between the client listing rooms and issuing the call.","commonSituations":"Stale room pickers in admin UIs; deletion races during room cleanup; hand-built scripts with typos in room ids.","solutions":["Verify the rid exists first (e.g. GET /v1/channels.info or rooms.info) before the bulk add.","Catch error-invalid-room and refresh the room list presented to the operator.","For scripts, resolve rid from a stable identifier (room name) at call time instead of hardcoding."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// verify the room exists immediately before the bulk add\nconst room = await fetch(`/api/v1/channels.info?roomId=${rid}`, { headers }).then((r) => r.json());\nif (!room.success) {\n\tthrow new Error(`Room ${rid} not found - refresh the room list`);\n}","typeGuard":null,"tryCatchPattern":"try {\n\tawait Meteor.callAsync('addAllUserToRoom', rid, activeUsersOnly);\n} catch (e: any) {\n\tif (e?.error === 'error-invalid-room') {\n\t\t// rid is stale: re-resolve the room and re-run with the fresh id\n\t}\n}","preventionTips":["Resolve rids at call time instead of hardcoding them.","Handle room-deleted events by invalidating cached room references.","Validate string rids (non-empty, expected format) before any room-scoped call."],"tags":["meteor-methods","rooms","not-found"],"backgroundTag":"room-not-found","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}