Discord定时禁言命令出现DiscordAPIError: Unknown Role错误求助
修复Discord定时禁言命令的角色恢复问题
首先,你遇到的Unknown Role错误主要出在几个细节上,我帮你拆解问题并给出完整的修复方案:
核心问题分析
- 权限判断逻辑错误:你用了
&&,这要求用户同时拥有MUTE_MEMBERS和MANAGE_ROLES权限才能执行命令,实际应该用||(只要具备其中一个权限即可)。 - @everyone角色误操作:你在移除用户所有角色时,把服务器默认的
@everyone角色也包含进去了——Discord API不允许手动移除或重新添加这个角色,这就是报错的直接原因。 - 缓存失效风险:延迟执行的
setTimeout里,原来的member对象可能因为用户离开服务器或缓存更新而失效,导致后续角色操作失败。
修复后的完整代码
const ms = require('ms'); module.exports = { name: 'mute', description: 'Mutes given user', async 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) { return message.reply('You need a user to mute!'); } const member = message.guild.members.cache.get(target.id); if (!member) { return message.reply('There was an error while attempting to get the member object of the mentioned user!'); } const muteRole = message.guild.roles.cache.find(role => role.name === "Muted"); if (!muteRole) { return message.reply('Make sure you have a role named "Muted" when trying to mute a member'); } // 过滤掉@everyone角色(其ID等于服务器ID),只保存用户的自定义角色 const userRoles = member.roles.cache .filter(role => role.id !== message.guild.id) .map(role => role.id); try { // 移除用户自定义角色并添加禁言角色 await member.roles.remove(userRoles); await member.roles.add(muteRole); message.reply(`Successfully muted ${target.tag} for ${args[1]}`); // 定时恢复角色,重新获取成员避免缓存失效 setTimeout(async () => { const updatedMember = message.guild.members.cache.get(target.id); if (!updatedMember) { return console.log(`User ${target.tag} is no longer in the server, can't restore roles.`); } try { await updatedMember.roles.remove(muteRole); await updatedMember.roles.add(userRoles); message.channel.send(`Unmuted ${target.tag} and restored their roles.`); } catch (err) { console.error('Error restoring roles:', err); message.channel.send(`Failed to restore roles for ${target.tag}: ${err.message}`); } }, ms(args[1])); } catch (err) { console.error('Error muting user:', err); message.reply(`Failed to mute user: ${err.message}`); } } };
额外优化建议
- 确保
Muted角色在服务器角色列表中的位置高于被禁言用户的其他角色,否则可能无法成功添加禁言角色(Discord的角色层级会影响权限生效)。 - 给
args[1]添加合法性校验,比如判断ms(args[1])是否为有效数字,避免因非法时间格式导致定时逻辑失效。 - 在服务器频道权限中给
Muted角色设置禁止发送消息的权限,才能真正实现禁言效果。
内容的提问来源于stack exchange,提问作者XRHTech




