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

Discord.js出现DiscordAPIError: Unknown Message错误原因排查问询

错误触发原因

你遇到的DiscordAPIError: Unknown Message(错误码10008,HTTP状态404)核心含义是调用delete方法的目标消息已经在Discord服务器中不存在,无法执行删除操作,具体触发逻辑如下:

  • 核心问题是重复绑定AudioPlayerStatus.Idle事件监听器:你每次发送播放提示消息时,都会通过client.player.on()新增一个Idle事件回调,这些回调不会自动销毁,会一直累积在播放器的事件队列中。
  • 当首次播放结束触发Idle事件时,所有累积的历史回调都会同时执行:最早绑定的回调会尝试删除已经被之前操作删掉的历史消息,自然就会抛出找不到消息的错误。
  • 你额外注册的全局Idle监听器会调用next.run()执行切歌逻辑,切歌时又会新增新的Idle监听器,进一步加剧监听器累积的问题。

解决方案

方案1:统一在全局Idle监听器中处理消息删除(更推荐)

不要每次发消息都新增监听器,把当前播放消息存储在client全局属性中,统一在已有的全局Idle监听器中处理删除,同时增加异常捕获避免偶发报错:
首先修改消息发送逻辑:

// 发送播放提示后将消息实例存储到client全局属性
client.nowPlayingMsg = await client.message.channel.send({
  content: `Song "${client.currentSong}" is playing`,
  components: [row],
});

然后修改全局Idle监听器逻辑:

client.player.on(AudioPlayerStatus.Idle, async () => {
  // 先处理历史播放消息删除
  if (client.nowPlayingMsg && client.nowPlayingMsg.deletable) {
    try {
      await client.nowPlayingMsg.delete();
    } catch (err) {
      // 捕获异常,消息已经被删除等场景直接忽略即可
    }
    client.nowPlayingMsg = null;
  }
  // 原有切歌逻辑不变
  if (!client.loop) client.playlist.shift();
  if (client.playlist.length === 0) return;
  next.run(client.message, client.args, client);
});

方案2:单次事件绑定+异常捕获

如果你要保留在消息发送处绑定回调的写法,将on改为once(单次事件监听,触发后自动销毁,不会累积),同时增加错误捕获:

await client.message.channel.send({
  content: `Song "${client.currentSong}" is playing`,
  components: [row],
})
.then(message => {
  // 用once替代on,只监听一次Idle事件,执行后自动销毁
  client.player.once(AudioPlayerStatus.Idle, async () => {
    try {
      if (message.deletable) await message.delete();
    } catch (e) {
      // 忽略删除失败场景
    }
  });
});

额外注意项

  • 确认机器人拥有目标频道的管理消息权限,否则会出现权限不足导致的删除失败
  • 若消息发送超过14天,Discord官方限制机器人无法删除此类消息,也会触发删除报错,可根据业务逻辑增加发送时间判断规避

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 05:36:02