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

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] });
      }
    }
  }
});

关键修改点

  1. setAuthor():从.setAuthor(name, iconURL)改为.setAuthor({ name: 'xxx', iconURL: 'xxx' })
  2. setFooter():从.setFooter(text)改为.setFooter({ text: 'xxx' })
  3. 编辑已有Embed:用EmbedBuilder.from()将API返回的Embed对象转换为可编辑的EmbedBuilder实例
  4. 代码优化:将require移到文件顶部,增加channel存在判断,避免不必要的报错

内容的提问来源于stack exchange,提问作者Eddie Kaspbrak

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 00:00:30