RocketChat/Rocket.Chat · error · Meteor.Error

error-invalid-user

error-invalid-user

Error message

There is no user with this username

What it means

Thrown by POST roles.removeUserFromRole when Users.findOneByUsername(username) returns null. The endpoint requires 'access-permissions' and the username came from the validated body. Returns a structured Meteor.Error('error-invalid-user', 'There is no user with this username').

Source

Thrown at apps/meteor/server/api/v1/roles.ts:287

				}),
				400: validateBadRequestErrorResponse,
				401: validateUnauthorizedErrorResponse,
				403: validateForbiddenErrorResponse,
			},
		},
		async function action() {
			const { bodyParams } = this;

			const { roleId, username, scope } = bodyParams;

			if (!roleId) {
				return API.v1.failure('error-invalid-role-properties');
			}

			const user = await Users.findOneByUsername(username);

			if (!user) {
				throw new Meteor.Error('error-invalid-user', 'There is no user with this username');
			}

			const role = await Roles.findOneById(roleId);

			if (!role) {
				throw new Meteor.Error('error-invalid-roleId', 'This role does not exist');
			}

			if (!(await hasAnyRoleAsync(user._id, [role._id], scope))) {
				throw new Meteor.Error('error-user-not-in-role', 'User is not in this role');
			}

			if (role._id === 'admin') {
				const adminCount = await Roles.countUsersInRole('admin');
				if (adminCount === 1) {
					throw new Meteor.Error('error-admin-required', 'You need to have at least one admin');
				}
			}

View on GitHub (pinned to f9d3ec372b)

Solutions

  1. Resolve the username from the users endpoint (e.g. users.info) before calling removeUserFromRole.
  2. Ensure you pass username (not _id, not email) as defined by isRoleRemoveUserFromRoleProps.
  3. Refresh cached usernames if the target may have been renamed.

Example fix

// before
await fetch('/api/v1/roles.removeUserFromRole', { method:'POST', body: JSON.stringify({ roleId, username: userId }) }); // wrong field

// after
await fetch('/api/v1/roles.removeUserFromRole', { method:'POST', body: JSON.stringify({ roleId, username }) });
Defensive patterns

Strategy: validation

Validate before calling

// Resolve a real username before removing from a role
const { user } = await fetch(`/api/v1/users.info?username=${encodeURIComponent(username)}`).then(r => r.json());
if (!user) throw new Error(`no user with username ${username}`);
await fetch('/api/v1/roles.removeUserFromRole', { method:'POST', body: JSON.stringify({ roleId, username: user.username }) });

Type guard

function isUsername(value: unknown): value is string {
  return typeof value === 'string' && value.trim().length > 0 && !value.includes('@') && !/^[a-z0-9]{17}$/i.test(value);
}

Prevention

When it happens

Trigger: POST /api/v1/roles.removeUserFromRole with a username that does not exist (typo, renamed/deactivated user, username vs user id confusion).

Common situations: Client sends the user _id or email instead of the username; the target user was renamed or deactivated and the username no longer resolves; cross-workspace username.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12). Data as JSON: /api/errors/d05be806bddab8d4. Report an issue: GitHub.