4
votes

I've gotten many errors in my code that I believe has been the result of mix-ups between GuildMembers and Users. Can someone explain the difference?

const user = message.mentions.users.first();

// TypeError: user.kick() is not a function
user.kick({ reason: 'spamming' });

// TypeError: user.ban() is not a function
user.ban({ reason: 'DM Advertising' });

// TypeError: message.author.hasPermission() is not a function
if (!message.author.hasPermission('ADMINISTRATOR')) return;

console.log(user.displayName); // undefined

// TypeError: message.member.createdAt() is not a function
embed.addField('Account Created', message.member.createdAt());

client.on('guildMemberUpdate', (oldMember, newMember) => {
 console.log(`${newMember.tag} was updated`); // 'undefined was updated'
});

if (message.member.bot) return; // undefined

// TypeError: Cannot read property 'add' of undefined
user.roles.add(newRole)

const target = message.client.users.cache.get(args[0])
console.log(target.displayName) // undefined
1

1 Answers

13
votes

From Official Discord.js Guide - Common Questions:

A lot of users get confused as to what the difference between Users and GuildMembers is. The simple answer is that a User represents a global Discord user and a GuildMember represents a Discord user on a specific server. That means only GuildMembers can have permissions, roles, and nicknames, for example, because all of these things are server-bound information that could be different on each server that user is in.


Many errors in the code in question occur because you are trying to call a guild specific function on a global user. For example, GuildMember.kick() and GuildMember.ban(). A very common mistake that leads to this is using the message.mentions.users collection. As the name suggests, this returns a collection of Users.

If you simply want, for example, the mentioned user's avatar, or maybe they're username and discriminator, it would work out fine. But it will lead to errors if you ever try to, for example, try to get the date they joined your server using GuildMember.joinedAt()

Luckily, there are many easy ways to circumvent this issue. For example, using MessageMentions.members (returns a collection of GuildMembers) instead of MessageMentions.users

const member = message.mentions.members.first()
member.ban() // no error here!

Another common workaround is using the Guild.member() method, which accepts a User object or ID!

const user = client.user // get the user object
const guild = client.guilds.cache.get('Guild ID') // get the guild object

const member = guild.member(user) // convert the User object to a GuildMember!

Other useful tricks to easily convert Users to GuildMembers include:

It's also very useful to remember if specific event parameters provide Users or GuildMembers. For example, both guildMemberAdd() and guildMemberUpdate pass GuildMembers, but messageReactionAdd(), guildBanAdd(), and typingStart() all pass Users.


While many GuildMember properties and methods are not available for a User, the same is true the other way around. For example, GuildMember.tag does not exist. However, converting a GuildMember to a User is much easier than converting a User to a GuildMember. This is because of GuildMember.user:

The user that this guild member instance represents

So, although GuildMember.tag will return undefined, GuildMember.user.tag will not!