RocketChat/Rocket.Chat · error · MeteorError
error-role-not-found
error-role-not-found
Error message
Role not found
What it means
After Roles.updateById succeeds and change notifications are broadcast, updateRole re-fetches the role; if findOneById now returns null it throws MeteorError('error-role-not-found', 'Role not found'). Because the role existed at the start of the function (checked at the top), this error signals the role was deleted concurrently between the initial lookup and the post-update re-fetch - a race, not a bad request.
Solutions
- Treat it as a conflict: re-check whether the role still exists; if it was intentionally deleted, the update is moot and can be dropped.
- If the update still matters, retry the whole operation against a role id that verifiably exists.
- Serialize role administration (single operator or tool at a time) so delete and update cannot interleave.
Example fix
// before
const updated = await updateRole(roleId, data); // throws error-role-not-found on a delete race
// after
try {
const updated = await updateRole(roleId, data);
} catch (e: any) {
if (e?.error === 'error-role-not-found' && !(await Roles.findOneById(roleId))) {
return; // role deleted concurrently; nothing left to update
}
throw e;
} Defensive patterns
Strategy: try-catch
Try / catch
try {
const updated = await updateRole(roleId, roleData);
} catch (e: any) {
if (e?.error === 'error-role-not-found' && !(await Roles.findOneById(roleId))) {
return; // deleted concurrently; the update is moot - reconcile and stop
}
throw e;
} Prevention
- Serialize role administration so a delete cannot interleave with an update.
- Build admin UIs to re-check existence right before save and after errors.
- Treat 'error-role-not-found' after a successful start-of-function lookup as a concurrency signal, not a bad request.
When it happens
Trigger: Two admins (or admin UI plus an API script) operating on the same role: one calls updateRole while the other deletes the role mid-flight; the update path completes its write and side effects, then fails to re-read the now-deleted document.
Common situations: Role management screens left open in multiple tabs; cleanup automation that removes 'unused' roles racing with manual edits; retrying an update against an id that was deleted between attempts.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- error-invalid-roleId
- error-action-not-allowed
- error-duplicate-role-names-not-allowed
- error-duplicate-role-names-not-allowed
- error-invalid-scope
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/03a7bbbb714449fd.
Report an issue: GitHub.
Appendix: source
Thrown at apps/meteor/ee/server/lib/roles/updateRole.ts:58
} else {
roleData.scope = role.scope;
}
await Roles.updateById(roleId, roleData.name, roleData.scope, roleData.description, roleData.mandatory2fa);
void notifyOnRoleChangedById(roleId);
if (options.broadcastUpdate) {
void api.broadcast('user.roleUpdate', {
type: 'changed',
_id: roleId,
scope: roleData.scope,
});
}
const updatedRole = await Roles.findOneById(roleId);
if (!updatedRole) {
throw new MeteorError('error-role-not-found', 'Role not found');
}
return updatedRole;
};
View on GitHub (pinned to b2c16d5842)