RocketChat/Rocket.Chat · error · MeteorError

error-role-not-found

error-role-not-found

Error message

Role not found

What it means

Thrown by updateRole in updateRole.ts:58 after the update was written — when a follow-up findOneById(roleId) returns null. This indicates the role was deleted between the updateById and the re-fetch (a TOCTOU race), or updateById silently affected zero docs and the role never existed at re-read time. MeteorError code 'error-role-not-found'.

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

Solutions

  1. Retry the read after a short delay; if still missing, treat as deleted.
  2. Investigate concurrent deletes / replication health if it recurs.
  3. Catch MeteorError 'error-role-not-found' and surface a stale-state message.

Example fix

// before
return await updateRole(roleId, roleData);

// after
try { return await updateRole(roleId, roleData); }
catch (e) {
  if (e.code === 'error-role-not-found') {
    // role deleted mid-update; refresh list
    return null;
  }
  throw e;
}
Defensive patterns

Strategy: retry

Validate before calling

// re-read right after update
const updated = await Roles.findOneById(roleId);
if (!updated) throw new Error('role not persisted');

Type guard

const roleStillExists = async (id: string) => Boolean(await Roles.findOneById(id, { projection: { _id: 1 } }));

Try / catch

try { return await updateRole(roleId, roleData); }
catch (e) {
  if (e?.code === 'error-role-not-found') return null; // deleted mid-update
  throw e;
}

Prevention

When it happens

Trigger: Concurrent delete of the role during the update call; a DB inconsistency where updateById did not persist. The earlier findOneById check at line 19 already confirmed existence, so this is almost always a race or DB fault.

Common situations: Two admins editing/deleting the same role simultaneously; replication lag in a multi-node deployment; failed write that did not throw.

Related errors


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