{"record":{"id":"012ca8aa07dce565","repo":"RocketChat/Rocket.Chat","slug":"error-invalid-arguments-012ca8","errorCode":"error-invalid-arguments","errorMessage":"Invalid arguments","messagePattern":"Invalid arguments","errorType":"error_code","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/meteor-methods/rooms/addUsersToRoom.ts","lineNumber":81,"sourceCode":"\tlet canAddUser = false;\n\tif (userInRoom && (await hasPermissionAsync(userId, 'add-user-to-joined-room', room._id))) {\n\t\tcanAddUser = true;\n\t} else if (room.t === 'c' && (await hasPermissionAsync(userId, 'add-user-to-any-c-room'))) {\n\t\tcanAddUser = true;\n\t} else if (room.t === 'p' && (await hasPermissionAsync(userId, 'add-user-to-any-p-room'))) {\n\t\tcanAddUser = true;\n\t}\n\n\t// Adding wasn't allowed\n\tif (!canAddUser) {\n\t\tthrow new Meteor.Error('error-not-allowed', 'Not allowed', {\n\t\t\tmethod: 'addUsersToRoom',\n\t\t});\n\t}\n\n\t// Missing the users to be added\n\tif (!Array.isArray(data.users)) {\n\t\tthrow new Meteor.Error('error-invalid-arguments', 'Invalid arguments', {\n\t\t\tmethod: 'addUsersToRoom',\n\t\t});\n\t}\n\n\tawait beforeAddUsersToRoom.run({ usernames: data.users, inviter: user }, room);\n\n\tawait Promise.all(\n\t\tdata.users.map(async (username) => {\n\t\t\tconst sanitizedUsername = sanitizeUsername(username);\n\n\t\t\tconst newUser = await Users.findOneByUsernameIgnoringCase(sanitizedUsername);\n\t\t\tif (!newUser) {\n\t\t\t\tthrow new Meteor.Error('error-user-not-found', 'User not found', {\n\t\t\t\t\tmethod: 'addUsersToRoom',\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst subscription = await Subscriptions.findOneByRoomIdAndUserId(data.rid, newUser._id);","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/meteor-methods/rooms/addUsersToRoom.ts#L63-L99","documentation":"Thrown by addUsersToRoomMethod() in apps/meteor/server/meteor-methods/rooms/addUsersToRoom.ts:81 when Array.isArray(data.users) is false. The users payload must be an array of usernames; the method then maps over it (data.users.map) in a Promise.all, so a non-array would crash the loop if not rejected here. Note this check runs after the permission checks, so an unauthorized caller gets error-not-allowed first.","triggerScenarios":"Passing data.users as a single username string, undefined (key missing), null, or an object; API shims mapping a REST body {username} directly to {users}; JSON inputs where users is an object map rather than an array.","commonSituations":"Client refactors renaming the field; type drift between callers written in JS and the TS signature; wrapping/unwrapping payloads incorrectly in automation scripts; the single-user 'addUserToRoom' wrapper being bypassed and the bulk method called with a scalar.","solutions":["Normalize to an array at the boundary: const users = Array.isArray(x) ? x : [x].filter(Boolean).","Validate the payload shape before calling (Match/Object schema or a manual typeof check).","If porting REST logic, remember the method takes usernames (strings), not user IDs or user objects.","Type the payload as { rid: string; users: string[] } at your call site so the compiler catches scalar mistakes."],"exampleFix":"// before\nawait addUsersToRoomMethod(uid, { rid, users: payload.username });\n\n// after\nconst users = Array.isArray(payload.users) ? payload.users : [payload.username].filter(Boolean);\nawait addUsersToRoomMethod(uid, { rid, users });","handlingStrategy":"type-guard","validationCode":"if (!Array.isArray(data.users)) {\n  data.users = [data.users].filter(Boolean);\n}","typeGuard":"const isUsernameArray = (v: unknown): v is string[] =>\n  Array.isArray(v) && v.every((x) => typeof x === 'string');","tryCatchPattern":"try {\n  await addUsersToRoomMethod(uid, { rid, users });\n} catch (e) {\n  if (e instanceof Meteor.Error && e.error === 'error-invalid-arguments') {\n    // normalize users to string[] and retry once\n  }\n}","preventionTips":["Validate the payload shape (Match/Object schema) at the boundary.","Type call sites as { rid: string; users: string[] }.\nWrap single values into arrays before passing them to bulk APIs."],"tags":["meteor-method","validation","arguments","type-error"],"backgroundTag":"invalid-method-arguments","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}