You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

discord.js V12 addrole命令报role.id相关错误排查

问题背景

discord.js升级至V13版本后,自行开发的Discord机器人addrole命令无法正常运行,执行时抛出role.id is not a function、role.id is not defined类错误。开发者具备较丰富JavaScript开发经验,确认自身代码逻辑无明显问题,尝试多种修复方案均未生效,初步怀疑故障与V12版本废弃后Discord API调用规则变动有关。
故障命令原实现代码如下:

const lineReplyNoMention = require('discord-reply');
const color = process.env.Color;
module.exports = {
    name: 'addrole',
    cooldown: 5,
    aliases: ['addnewrole'],
    permissions: ["MANAGE_ROLES"],
    clientpermissions: ["MANAGE_ROLES", "SEND_MESSAGES", "EMBED_LINKS"],
    async execute(client, message, cmd, args, Discord) {
        const user = message.mentions.users.first();
        const usertarget = message.guilds.members.cache.get(user.id);
        if (!user) {
            const nopr = new Discord.MessageEmbed().setTimestamp().setColor(`${color}`).setAuthor(`${message.author.username}`, message.author.displayAvatarURL({ dynamic: true })).setDescription(`**\`(prefix)addrole <@user> <@role>\`**`)
            return message.lineReplyNoMention({ embed: nopr })
        }
        args.shift()
        const roleToGive = message.mentions.roles.first()
        if (!roleToGive) {
            const addroleError2 = new Discord.MessageEmbed().setTimestamp().setDescription(`**No Roles Provided!**`).setColor(`${color}`)
            return message.lineReplyNoMention({ embed: addroleError2 })
        }
        usertarget.roles.add(roleToGive.id)
        const embed = new Discord.MessageEmbed().setTimestamp().setColor(`${color}`).setAuthor(`${message.author.username}`, message.author.displayAvatarURL({ dynamic: true })).setDescription(`**Added: \`${roleToGive}\` To \`${user.username}\`**`)
        message.lineReplyNoMention({ embed: embed })
    }
}
故障根因

代码存在4处和V13版本不兼容/书写错误的问题,和V12版本废弃无直接关联:

  • 基础拼写错误:获取目标服务器成员时使用了message.guilds.members.cache,discord.js中单条消息所属的服务器对象属性为单数形式message.guild,message.guilds是客户端级别的所有服务器缓存,在消息对象上直接调用会返回undefined,后续读取成员属性自然会报未定义错误。
  • 边界判断缺失:代码未判断目标成员对象是否真实存在,如果提及的用户不在当前服务器内,后续执行加角色操作时会直接触发属性读取错误。
  • V13接口适配遗漏:discord.js V13调整了消息发送参数格式,原V12版本中传入单embed的embed字段,在V13中改为复数形式embeds,要求传入embed数组;同时roles.add()是异步方法,原代码未加await也未做错误捕获,执行时序异常时也会触发报错。
  • 第三方依赖兼容问题:使用的discord-reply包如果是适配V12的旧版本,在V13运行环境下会破坏message对象原型链,间接导致角色、成员相关属性读取失败。
修复方案
  • 将message.guilds修正为message.guild
  • 补充目标成员存在性判断
  • 适配V13消息发送参数格式,将所有embed字段替换为embeds数组
  • 给异步的加角色方法添加await和错误捕获
  • 如果discord-reply包运行异常,可以直接用原生message.reply配合allowedMentions参数实现不@回复效果,无需额外依赖
  • 补充机器人角色层级判断,避免因角色权限不足触发API报错

修复后可正常运行的代码如下:

const color = process.env.Color;
module.exports = {
    name: 'addrole',
    cooldown: 5,
    aliases: ['addnewrole'],
    permissions: ["MANAGE_ROLES"],
    clientpermissions: ["MANAGE_ROLES", "SEND_MESSAGES", "EMBED_LINKS"],
    async execute(client, message, cmd, args, Discord) {
        const user = message.mentions.users.first();
        if (!user) {
            const nopr = new Discord.MessageEmbed()
                .setTimestamp()
                .setColor(color)
                .setAuthor(message.author.username, message.author.displayAvatarURL({ dynamic: true }))
                .setDescription(`**\`(prefix)addrole <@user> <@role>\`**`)
            return message.reply({
                embeds: [nopr],
                allowedMentions: { repliedUser: false }
            })
        }
        // 修正guild拼写,补充成员存在判断
        const usertarget = message.guild.members.cache.get(user.id);
        if (!usertarget) {
            const noMember = new Discord.MessageEmbed()
                .setTimestamp()
                .setColor(color)
                .setDescription(`**目标用户不在当前服务器内**`)
            return message.reply({
                embeds: [noMember],
                allowedMentions: { repliedUser: false }
            })
        }
        args.shift()
        const roleToGive = message.mentions.roles.first()
        if (!roleToGive) {
            const addroleError2 = new Discord.MessageEmbed()
                .setTimestamp()
                .setDescription(`**未提供要添加的角色**`)
                .setColor(color)
            return message.reply({
                embeds: [addroleError2],
                allowedMentions: { repliedUser: false }
            })
        }
        // 补充角色位置权限判断,避免权限不足报错
        if (message.guild.me.roles.highest.position <= roleToGive.position) {
            const permErr = new Discord.MessageEmbed()
                .setTimestamp()
                .setDescription(`**机器人角色权限不足,无法分配该角色**`)
                .setColor(color)
            return message.reply({
                embeds: [permErr],
                allowedMentions: { repliedUser: false }
            })
        }
        await usertarget.roles.add(roleToGive.id).catch(e => {
            const errEmbed = new Discord.MessageEmbed()
                .setTimestamp()
                .setDescription(`**添加角色失败:${e.message}**`)
                .setColor(color)
            return message.reply({
                embeds: [errEmbed],
                allowedMentions: { repliedUser: false }
            })
        })
        const embed = new Discord.MessageEmbed()
            .setTimestamp()
            .setColor(color)
            .setAuthor(message.author.username, message.author.displayAvatarURL({ dynamic: true }))
            .setDescription(`**已将角色 \`${roleToGive.name}\` 分配给 \`${user.username}\`**`)
        message.reply({
            embeds: [embed],
            allowedMentions: { repliedUser: false }
        })
    }
}

注意:运行V13版本discord.js时,需要在客户端初始化时开启GUILDS、GUILD_MEMBERS、GUILD_MESSAGES、GUILD_ROLES相关Intents,同时在Discord开发者后台开启对应服务器成员权限开关,否则缓存无法正常加载成员、角色数据。

内容的提问来源于stack exchange,提问作者Brandon Torreglosa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 19:31:41