RocketChat/Rocket.Chat · error · Meteor.Error
error-user-has-no-roles
error-user-has-no-roles
Error message
User has no roles
What it means
validateLoginAttempt throws error-user-has-no-roles when login.user.roles is missing or not an array. Rocket.Chat assumes every human user carries a roles array (at minimum 'user'); a document without it is treated as corrupt because all later authorization (hasPermission) would behave unpredictably.
Source
Thrown at apps/meteor/server/lib/auth/startup.js:445
if (login.user.type === 'visitor') {
return true;
}
if (login.user.type === 'app') {
throw new Meteor.Error('error-app-user-is-not-allowed-to-login', 'App user is not allowed to login', {
function: 'Accounts.validateLoginAttempt',
});
}
if (!!login.user.active !== true) {
throw new Meteor.Error('error-user-is-not-activated', 'User is not activated', {
function: 'Accounts.validateLoginAttempt',
});
}
if (!login.user.roles || !Array.isArray(login.user.roles)) {
throw new Meteor.Error('error-user-has-no-roles', 'User has no roles', {
function: 'Accounts.validateLoginAttempt',
});
}
if (login.user.roles.includes('admin') === false && login.type === 'password' && settings.get('Accounts_EmailVerification') === true) {
const validEmail = login.user.emails.filter((email) => email.verified === true);
if (validEmail.length === 0) {
throw new Meteor.Error('error-invalid-email', 'Invalid email __email__');
}
}
login = await callbacks.run('onValidateLogin', login);
await Users.updateLastLoginById(login.user._id);
setImmediate(() => {
return callbacks.run('afterValidateLogin', login);
});
View on GitHub (pinned to b2c16d5842)
Solutions
- Re-assign roles in Administration -> Users -> edit the user -> Roles (typically add 'user')
- Repair the document directly: db.users.updateOne({ _id: '<uid>' }, { $set: { roles: ['user'] } })
- Ensure migrations ran after upgrades (check the migrations collection and server startup logs)
- Always create users through Accounts.createUser or the admin APIs so defaults are applied
Example fix
// before (broken doc)
// db.users.findOne(uid) -> { _id: uid, username: 'bob', roles: null }
// after
// mongo shell:
db.users.updateOne({ _id: uid }, { $set: { roles: ['user'] } }); Defensive patterns
Strategy: type-guard
Validate before calling
const user = await Users.findOneById(uid);
if (!hasValidRoles(user)) {
await Users.updateOne({ _id: uid }, { $set: { roles: ['user'] } }); // repair before login is attempted
} Type guard
const hasValidRoles = (u: unknown): u is { roles: string[] } =>
typeof u === 'object' && u !== null && Array.isArray((u as { roles?: unknown }).roles); Try / catch
try {
await loginWithPassword(user, password);
} catch (e) {
if (e instanceof Meteor.Error && e.error === 'error-user-has-no-roles') {
// data corruption: repair roles via admin/db, then retry once
}
throw e;
} Prevention
- Create users only via Accounts.createUser / admin APIs so roles defaults are applied
- Run and verify migrations after restores and upgrades
- Add a data-audit step after bulk imports checking that every user has a non-empty roles array
When it happens
Trigger: Login as a user whose Mongo document lacks roles or stores it as a non-array (null, string, object) — after manual database surgery, a partial restore, a skipped migration, or custom code inserting users directly into the Users collection.
Common situations: Users inserted via mongoimport or scripts bypassing Accounts.createUser; database restored from a much older version without running migrations; a manual cleanup deleted the roles field instead of emptying it.
Related errors
- error-user-is-not-activated
- error-invalid-user
- error-login-blocked-for-ip
- error-login-blocked-for-user
- error-app-user-is-not-allowed-to-login
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/f58268f546098235.
Report an issue: GitHub.