Skip to content

Timed Mute Command ‘UnhandledPromiseRejectionWarning: DiscordAPIError: Unknown Role’ error

I’m making a timed mute command, but i get a lot of errors, the principal one being :

(node:6584) UnhandledPromiseRejectionWarning: DiscordAPIError: Unknown Role
    at RequestHandler.execute (c:UsersuserDesktopDiscordJSBOTnode_modulesdiscord.jssrcrestRequestHandler.js:154:13)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at async RequestHandler.push (c:UsersuserDesktopDiscordJSBOTnode_modulesdiscord.jssrcrestRequestHandler.js:39:14)
    at async GuildMemberRoleManager.remove (c:UsersuserDesktopDiscordJSBOTnode_modulesdiscord.jssrcmanagersGuildMemberRoleManager.js:125:7)
(Use `node --trace-warnings ...` to show where the warning was created)

Here is the bugged code :

const ms = require('ms');

module.exports = {
    name : 'mute',
    description: 'Mutes given user',
    
    execute(client, message, args) {
        
        if(!message.member.hasPermission('MUTE_MEMBERS') && message.member.hasPermission('MANAGE_ROLES')) {
            return message.reply('You need permissions to use this command !');
        }
        
        const target = message.mentions.users.first();
        if(target) {
            const member = message.guild.members.cache.get(target.id)
            
            if(member) {
                const muteRole = message.guild.roles.cache.find(role => role.name === "Muted");
                
                if(muteRole) {
                    const RoleFolder = []
                    const roles = member.roles.cache.map(role => role);

                    roles.forEach(role => {
                        RoleFolder.push(role.id)
                        member.roles.remove(role.id)
                    });
                    member.roles.add(muteRole.id)

                    setTimeout(function () {
                        member.roles.remove(muteRole.id)
                        RoleFolder.forEach(roles => {
                            member.roles.add(roles)
                        })
                    }, ms(args[1]));

                } else {
                    return message.reply('Make sure you have a role nammed "Muted" when trying to mute a member');
                }
            } else {
                return message.reply('There was an error while attempting to get member object of mentioned user !')
            }
        } else {
            return message.reply('You need a user to mute ! ');
        }
    }
}

The problem comes from the fact that I get all roles from the user, store it and then give it back. I don’t know if there is any other way to do it but that’s what I found.

Thanks !

Answer

The error DiscordAPIError: Unknown Role is showing up because you are trying to remove a role from a user that the discord API cannot find. This role is the @everyone role which all members have.

You also do not need to run map on the roles, as you can already iterrate over the cache collection.

The code in your question:

const RoleFolder = []
const roles = member.roles.cache.map(role => role);
roles.forEach(role => {
    RoleFolder.push(role.id)
    member.roles.remove(role.id)
});

Can be changed to:

const RoleFolder = []
member.roles.cache.forEach(role => {
    if (role.id === member.guild.id) return;
    RoleFolder.push(role.id)
    member.roles.remove(role.id)
});

To ignore the role that doesn’t exist in the discord API, you can check for:

role.id === member.guild.id or role.rawPosition === 0

You can use return to skip executing code for that particular role, meaning it isn’t added to the RoleFolder, and doesn’t try to remove the role.

Edit: I would avoid using role.name === '@everyone' as a user can create a role called @everyone and this would be missed, so I have updated my answer to check for a better condition.