RocketChat/Rocket.Chat · error · Meteor.Error
error-users-params-not-provided
error-users-params-not-provided
Error message
Please provide "userId" or "username" or "userIds" or "usernames" as param
What it means
Thrown by getUserListFromParams when, after merging the single-user params (userId/username/user) with the array params (userIds/usernames), filtering out falsy entries and deduplicating, the resulting list is empty. In other words the request carried none of the accepted user identifier params, or only empty/whitespace values that filter(Boolean) removed (note the helper pushes soleUser || '' and then strips empty strings).
Source
Thrown at apps/meteor/server/api/lib/getUserFromParams.ts:58
export async function getUserListFromParams(params: {
userId?: string;
username?: string;
user?: string;
userIds?: string[];
usernames?: string[];
}): Promise<Pick<IUser, '_id' | 'username'>[]> {
// if params.userId is provided, include it as well
const soleUser = params.userId || params.username || params.user;
let userListParam = params.userIds || params.usernames || [];
userListParam.push(soleUser || '');
userListParam = userListParam.filter(Boolean);
// deduplicate to avoid errors
userListParam = [...new Set(userListParam)];
if (!userListParam.length) {
throw new Meteor.Error('error-users-params-not-provided', 'Please provide "userId" or "username" or "userIds" or "usernames" as param');
}
if (params.userIds || params.userId) {
return Users.findByIds(userListParam, { projection: { username: 1 } }).toArray();
}
return Users.findByUsernamesIgnoringCase(userListParam, { projection: { username: 1 } }).toArray();
}
/**
* Resolves a list of usernames from the request params without requiring the users to
* already exist locally. `username`/`usernames`/`user` are passed through verbatim, while
* `userId`/`userIds` are resolved to their usernames via the database.
*
* Unlike `getUserListFromParams`, this does not drop usernames that have no local record yet
* — which is what federation invites rely on: the federated user record is created lazily
* inside `addUsersToRoomMethod`.
*/View on GitHub (pinned to b2c16d5842)
Solutions
- Include at least one non-empty value among userId, username, user, userIds, usernames
- Guard on the client: skip the API call (or disable the submit button) when the combined identifier list is empty
- Check exact param spelling and casing against the endpoint docs — unknown params are ignored, not rejected
- URL-encode array params properly (userIds[]=a&userIds[]=b) so they survive the query string
Example fix
// before
POST /api/v1/channels.addAllRoles { "roomId": "abc", "userIds": [] }
// after
POST /api/v1/channels.addAllRoles { "roomId": "abc", "userIds": ["aobEdbYhXfu5hkeqG"] } Defensive patterns
Strategy: validation
Validate before calling
function hasUserListParam(p: { userId?: string; username?: string; user?: string; userIds?: string[]; usernames?: string[] }): boolean {
const sole = [p.userId, p.username, p.user].some((v) => typeof v === 'string' && v.trim() !== '');
const list = [...(p.userIds ?? []), ...(p.usernames ?? [])].some((v) => typeof v === 'string' && v.trim() !== '');
return sole || list;
}
// if (!hasUserListParam(params)) skip the request with a client-side error Try / catch
try {
await client.post('/api/v1/channels.addAllRoles', body);
} catch (e: any) {
if (e?.response?.data?.errorType === 'error-users-params-not-provided') {
throw new ValidationError('at least one of userId/username/user/userIds/usernames is required');
}
throw e;
} Prevention
- Disable submit actions when the selected-users list is empty
- Mirror the server's precedence (userId > username > user; arrays merged) when building params
- Spell params exactly as documented; unknown keys are silently ignored server-side
When it happens
Trigger: POST/GET to an endpoint using this helper (e.g. bulk member operations routed through apps/meteor/server/api/v1/{channels,groups,im,users}.ts) with an empty body, with userIds=[] / usernames=[] empty arrays, or with whitespace-only strings. A typo'd param name (user_id, userName) is silently ignored and produces the same throw.
Common situations: Frontend multi-select submitted with nothing chosen so the client posts {userIds: []}; param name mismatch after an API client refactor; query string not URL-encoded so the value arrives empty; integration code that conditionally builds params and skips all branches.
Understand the failure class
Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.
Related errors
- error-invalid-sort
- error-invalid-fields
- error-invalid-query
- error-invalid-search-answer-sources
- Type not supported
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/a8edf78e53493784.
Report an issue: GitHub.