Discord.js 14.11.0添加星标表情时Embed构建报错求助
Discord.js 14.11.0 Embed构建报错:ValidationError 解决方法
我在Discord.js 14.11.0中构建Embed时,每次添加星标表情都会触发以下ValidationError,导致消息无法发送:
node:events:491 throw er; // Unhandled 'error' event ^ ValidationError: Expected the value to be an object, but received string instead at ObjectValidator.handle (C:\Users\bgang\Desktop\New folder (3)\node_modules\@sapphire\shapeshift\dist\index.js:1207:25) at ObjectValidator.parse (C:\Users\bgang\Desktop\New folder (3)\node_modules\@sapphire\shapeshift\dist\index.js:212:88) at EmbedBuilder.setAuthor (C:\Users\bgang\Desktop\New folder (3)\node_modules\@discordjs\builders\dist\index.js:291:26) at Client.<anonymous> (C:\Users\bgang\Desktop\New folder (3)\index.js:26:12) at Client.emit (node:events:513:28) at MessageReactionAdd.handle (C:\Users\bgang\Desktop\New folder (3)\node_modules\discord.js\src\client\actions\MessageReactionAdd.js:49:17) at module.exports [as MESSAGE_REACTION_ADD] (C:\Users\bgang\Desktop\New folder (3)\node_modules\discord.js\src\client\websocket\handlers\MESSAGE_REACTION_ADD.js:4:37) at WebSocketManager.handlePacket (C:\Users\bgang\Desktop\New folder (3)\node_modules\discord.js\src\client\websocket\WebSocketManager.js:354:31) at WebSocketManager.<anonymous> (C:\Users\bgang\Desktop\New folder (3)\node_modules\discord.js\src\client\websocket\WebSocketManager.js:238:12) at WebSocketManager.emit (C:\Users\bgang\Desktop\New folder (3)\node_modules\@vladfrangu\async_event_emitter\dist\index.js:282:31) Emitted 'error' event on Client instance at: at emitUnhandledRejectionOrErr (node:events:394:10) at process.processTicksAndRejections (node:internal/process/task_queues:84:21) { validator: 's.object(T)', given: 'eddieafk#0' }
相关代码如下:
client.on('messageReactionAdd', async (reaction, user) => { if (reaction.emoji.name === '⭐' && reaction.count > 1) { const message = reaction.message; const channel = message.guild.channels.cache.get(starboardChannelId); const { EmbedBuilder } = require("discord.js") const embed = new EmbedBuilder() .setColor('#FFAC33') .setAuthor(message.author.tag, message.author.displayAvatarURL()) .setDescription(`${message.content}`) .setFooter(`⭐ 1 • ${message.id}`) .setTimestamp(); if (message.attachments.size > 0) { const attachment = message.attachments.first(); if (attachment) { embed.setImage(attachment.url); } } await channel.send({ embeds: [embed] }); if (channel) { const fetchMessages = await channel.messages.fetch({ limit: 100 }); const starboardMessage = fetchMessages.find(m => m.embeds.length && m.embeds[0].footer.text.startsWith('⭐') && m.embeds[0].footer.text.endsWith(message.id)); if (starboardMessage) { const embed = starboardMessage.embeds[0]; const starCount = embed.footer.text.match(/⭐ (\d+)/)[1]; const newEmbed = embed.setFooter(`⭐ ${parseInt(starCount) + 1} • ${message.id}`); await starboardMessage.edit({ embeds: [newEmbed] }); } else { } } } });
错误原因
Discord.js v14版本对EmbedBuilder的API做了变更:setAuthor()和setFooter()不再接受分开的参数(比如用户名、头像URL),必须传入一个包含对应属性的对象。你的代码中直接传递字符串和URL,不符合v14的类型要求,因此触发了验证错误。
修复后的代码
修改setAuthor()和setFooter()的调用方式,同时注意编辑已有Embed时,需要先将API返回的Embed对象转换为EmbedBuilder实例再修改:
// 建议把require移到文件顶部,不要放在事件回调里 const { EmbedBuilder } = require("discord.js"); client.on('messageReactionAdd', async (reaction, user) => { if (reaction.emoji.name === '⭐' && reaction.count > 1) { const message = reaction.message; const channel = message.guild.channels.cache.get(starboardChannelId); const embed = new EmbedBuilder() .setColor('#FFAC33') // 修改setAuthor为对象传参 .setAuthor({ name: message.author.tag, iconURL: message.author.displayAvatarURL() }) .setDescription(`${message.content}`) // 修改setFooter为对象传参 .setFooter({ text: `⭐ 1 • ${message.id}` }) .setTimestamp(); if (message.attachments.size > 0) { const attachment = message.attachments.first(); if (attachment) { embed.setImage(attachment.url); } } // 先判断channel存在再发送,避免报错 if (channel) { const fetchMessages = await channel.messages.fetch({ limit: 100 }); const starboardMessage = fetchMessages.find(m => m.embeds.length && m.embeds[0].footer?.text?.startsWith('⭐') && m.embeds[0].footer?.text?.endsWith(message.id)); if (starboardMessage) { // 将旧Embed转换为EmbedBuilder实例再修改 const existingEmbed = EmbedBuilder.from(starboardMessage.embeds[0]); const starCount = existingEmbed.data.footer.text.match(/⭐ (\d+)/)[1]; const newEmbed = existingEmbed.setFooter({ text: `⭐ ${parseInt(starCount) + 1} • ${message.id}` }); await starboardMessage.edit({ embeds: [newEmbed] }); } else { // 没有旧消息时发送新Embed await channel.send({ embeds: [embed] }); } } } });
关键修改点
setAuthor():从.setAuthor(name, iconURL)改为.setAuthor({ name: 'xxx', iconURL: 'xxx' })setFooter():从.setFooter(text)改为.setFooter({ text: 'xxx' })- 编辑已有Embed:用
EmbedBuilder.from()将API返回的Embed对象转换为可编辑的EmbedBuilder实例 - 代码优化:将
require移到文件顶部,增加channel存在判断,避免不必要的报错
内容的提问来源于stack exchange,提问作者Eddie Kaspbrak
相关产品推荐
相关产品推荐

