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

Discord.js v14+DisTube v4断开语音频道代码报错求助

问题:Discord.js v14 + DisTube v4 断开语音频道功能报错 TypeError: Cannot read properties of undefined (reading 'cache')

报错信息

node:events:491
      throw er; // Unhandled 'error' event
      ^

TypeError: Cannot read properties of undefined (reading 'cache')
    at Client.<anonymous> (C:\Users\Alberto\Desktop\Bot discord\index.js:119:32)
    at Client.emit (node:events:513:28)
    at MessageCreateAction.handle (C:\Users\Alberto\Desktop\Bot discord\node_modules\discord.js\src\client\actions\MessageCreate.js:28:14)
    at module.exports [as MESSAGE_CREATE] (C:\Users\Alberto\Desktop\Bot discord\node_modules\discord.js\src\client\websocket\handlers\MESSAGE_CREATE.js:4:32)
    at WebSocketManager.handlePacket (C:\Users\Alberto\Desktop\Bot discord\node_modules\discord.js\src\client\websocket\WebSocketManager.js:352:31)
    at WebSocketShard.onPacket (C:\Users\Alberto\Desktop\Bot discord\node_modules\discord.js\src\client\websocket\WebSocketShard.js:494:22)
    at WebSocketShard.onMessage (C:\Users\Alberto\Desktop\Bot discord\node_modules\discord.js\src\client\websocket\WebSocketShard.js:328:10)
    at callListener (C:\Users\Alberto\Desktop\Bot discord\node_modules\ws\lib\event-target.js:290:14)
    at WebSocket.onMessage (C:\Users\Alberto\Desktop\Bot discord\node_modules\ws\lib\event-target.js:209:9)
    at WebSocket.emit (node:events:513:28)
Emitted 'error' event on Client instance at:
    at emitUnhandledRejectionOrErr (node:events:394:10)
    at process.processTicksAndRejections (node:internal/process/task_queues:84:21)

原代码

else if (command === 'leave') {
  
  const guild = message.guilds.cache.get('guild-id');
  const voiceChannel = guild.guild.channels.cache.get('voice-channel-id');
  
  const channel = message.member.voice.channel;
  
  if (!channel) return message.channel.send('You need to be in a voice channel to do this');
  if (voiceChannel && voiceChannel.members.has(client.user.id)) console.log('The bot is connected to the voice channel.');
  else {return message.channel.send("I'm not in a voice channel")}

  const channelId = connection.packets.state.channel_id

  if (channel.id !== channelId) return message.channel.send('You need to be in the same voice channel as me')

  try{await
    connection.destroy()
    message.channel.send('Sono uscito dalla chat vocale');
  } catch(error){
  console.error(error);}
  
}

错误原因与修复方案

核心错误点

  1. message.guilds 属性不存在:Discord.js v14 中,message 对象的服务器属性是 message.guild,而非 message.guilds,直接访问 message.guilds.cache 会因 message.guilds 为 undefined 触发报错。
  2. 重复调用 guild.guild:获取到 guild 对象后,无需额外调用 .guild,直接使用 guild.channels 即可。
  3. 硬编码ID无意义:无需手动指定服务器和语音频道ID,可通过消息上下文或机器人当前连接状态动态获取。
  4. connection 变量未定义:原代码中直接使用 connection 但未声明,需通过Discord.js或DisTube的API获取当前语音连接。

修正后的代码(Discord.js原生实现)

结合需求(验证发送者/机器人的语音状态、断开频道),修正后的代码如下:

else if (command === 'leave') {
  // 获取指令发送者所在的语音频道
  const userVoiceChannel = message.member.voice.channel;
  // 获取机器人当前所在的语音频道
  const botVoiceChannel = message.guild.members.me.voice.channel;

  // 验证1:发送者是否在语音频道
  if (!userVoiceChannel) {
    return message.channel.send('你需要先加入一个语音频道才能执行此指令');
  }

  // 验证2:机器人是否在语音频道
  if (!botVoiceChannel) {
    return message.channel.send('我当前没有连接到任何语音频道');
  }

  // 验证3:发送者和机器人是否在同一频道
  if (userVoiceChannel.id !== botVoiceChannel.id) {
    return message.channel.send('你需要和我在同一个语音频道才能让我退出');
  }

  // 断开语音连接
  try {
    await botVoiceChannel.leave();
    message.channel.send('我已退出语音频道');
  } catch (error) {
    console.error('退出语音频道时出错:', error);
    message.channel.send('退出语音频道时发生错误,请稍后再试');
  }
}

若使用DisTube的替代方案

如果你是通过DisTube管理语音连接,也可以用DisTube的API断开:

else if (command === 'leave') {
  const userVoiceChannel = message.member.voice.channel;
  const distube = client.distube; // 假设你已将DisTube实例挂载到client上

  if (!userVoiceChannel) {
    return message.channel.send('你需要先加入一个语音频道才能执行此指令');
  }

  const queue = distube.getQueue(message.guildId);
  if (!queue) {
    return message.channel.send('我当前没有在播放音乐,无需退出频道');
  }

  if (userVoiceChannel.id !== queue.voiceChannel.id) {
    return message.channel.send('你需要和我在同一个语音频道才能让我退出');
  }

  try {
    distube.voices.leave(message.guildId);
    message.channel.send('我已退出语音频道');
  } catch (error) {
    console.error('退出语音频道时出错:', error);
    message.channel.send('退出语音频道时发生错误,请稍后再试');
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 00:15:08