RocketChat/Rocket.Chat · error · Meteor.Error

error-invalid-user

error-invalid-user

Error message

The required "userId" or "username" param provided does not match any users

What it means

Thrown by getUserFromParams, the shared REST v1 helper that resolves a user from request params. Params are checked in priority order: userId (exact _id lookup), then username, then user (both case-insensitive username lookups). If one param was supplied but no user document matches it, the helper throws error-invalid-user. This is a 'value supplied but nothing found' error, distinct from error-user-param-not-provided which fires when no param is given at all.

Source

Thrown at apps/meteor/server/api/lib/getUserFromParams.ts:35

		: Pick<IUser, '_id' | 'username' | 'name' | 'status' | 'statusDefault' | 'statusText' | 'statusSource' | 'statusExpiresAt' | 'roles'>
> {
	let user;

	const projection = full
		? {}
		: { username: 1, name: 1, status: 1, statusDefault: 1, statusText: 1, statusSource: 1, statusExpiresAt: 1, roles: 1 };
	if (params.userId?.trim()) {
		user = await Users.findOneById(params.userId, { projection });
	} else if (params.username?.trim()) {
		user = await Users.findOneByUsernameIgnoringCase(params.username, { projection });
	} else if (params.user?.trim()) {
		user = await Users.findOneByUsernameIgnoringCase(params.user, { projection });
	} else {
		throw new Meteor.Error('error-user-param-not-provided', 'The required "userId" or "username" param was not provided');
	}

	if (!user) {
		throw new Meteor.Error('error-invalid-user', 'The required "userId" or "username" param provided does not match any users');
	}

	return user;
}

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);

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Verify the user exists first with GET /api/v1/users.info?username=<value> (or ?userId=) to see which identifier resolves
  2. Make sure usernames go into the username or user param and Mongo _ids into userId — userId is matched by _id only, not by name
  3. Trim and URL-decode the value; check for invisible characters or broken JSON encoding in the query string
  4. If the user was deleted or lives on a federated server, re-create/resolve the account or use its local username

Example fix

// before
GET /api/v1/users.info?userId=rocket.cat   // username wrongly used as _id

// after
GET /api/v1/users.info?username=rocket.cat // or ?userId=aobEdbYhXfu5hkeqG
Defensive patterns

Strategy: validation

Validate before calling

async function resolveUserIdent(client, userIdOrName: string): Promise<string> {
  // users.info accepts either param and 404s cleanly when absent
  const r = await client.get('/api/v1/users.info', { params: { userId: userIdOrName } });
  if (r.ok) return r.data.user._id;
  const byName = await client.get('/api/v1/users.info', { params: { username: userIdOrName } });
  if (byName.ok) return byName.data.user._id;
  throw new Error(`no user matches ${userIdOrName}`);
}

Type guard

const isUserRef = (v: unknown): v is { userId?: string; username?: string; user?: string } =>
  typeof v === 'object' && v !== null && !Array.isArray(v) &&
  Object.values(v).some((x) => typeof x === 'string' && x.trim() !== '');

Try / catch

try {
  await client.get('/api/v1/channels.info', { params: { username } });
} catch (e: any) {
  if (e?.response?.data?.errorType === 'error-invalid-user') {
    // treat as 404: identifier valid but no such user
    throw new NotFoundError(`user ${username} not found`);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling any REST v1 endpoint backed by this helper (users.info-style flows in apps/meteor/server/api/v1/{users,channels,groups,rooms,misc,roles}.ts) with a userId that is not a real user _id, or a username/user value that matches no username. Typical: passing the username 'rocket.cat' inside the userId param (it is then looked up as an _id and fails), quoting the ID with stray whitespace, or referencing a user that was deleted.

Common situations: Client cached a stale userId across a workspace reset or user deletion; copy-pasting a username where an _id belongs; federation setups where the user exists on another server but not locally; renamed users when the old username was stored.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18). Data as JSON: /api/errors/97ce75f20986f960. Report an issue: GitHub.