Discord.js v12.4音乐机器人?play指令触发message.member.voice未定义错误问询
问题根因
TypeError: Cannot read property 'voice' of undefined 错误说明你调用voice属性的上层对象message.member为undefined,和voice、voiceChannel的写法无关,你之前查到的写法更新方案适用于message.member存在的场景,不匹配你当前的问题。
常见导致message.member为undefined的原因有3种:
- 指令在私聊频道触发,只有服务器(公会)频道的消息才会携带
member属性 - 主文件调用
execute函数时的参数传递顺序错误,导致当前文件接收到的message不是真实的消息对象 - 机器人未开启
GUILD_MEMBERS特权网关意图,无法正确获取服务器成员对象
修复步骤
- 先添加调试代码确认问题
在第14行之前插入以下代码,触发指令后查看控制台输出:
console.log('频道类型:', message.channel.type); console.log('是否存在member属性:', !!message.member);
如果输出的频道类型为dm,说明指令是私聊触发的,直接在指令执行前添加限制逻辑即可:
if (message.channel.type === 'dm') return message.reply('该指令仅可在服务器频道使用');
- 核对主文件的
execute调用参数
你当前导出的execute参数顺序为(message, args, cmd, client, Discord),主文件调用时必须严格按照该顺序传参,参考正确写法:
// 主文件消息监听逻辑示例 client.on('message', async message => { const prefix = '?'; if (!message.content.startsWith(prefix) || message.author.bot) return; const args = message.content.slice(prefix.length).trim().split(/ +/); const cmd = args.shift().toLowerCase(); const command = client.commands.get(cmd) || client.commands.find(c => c.aliases?.includes(cmd)); if (command) { // 传参顺序必须和导出的execute完全匹配 command.execute(message, args, cmd, client, Discord); } })
- 开启必要的网关意图
首先在Discord开发者后台的机器人设置页,开启Privileged Gateway Intents下的Server Members Intent开关,然后在主文件初始化客户端时声明需要的意图:
const client = new Discord.Client({ ws: { intents: ['GUILDS', 'GUILD_MESSAGES', 'GUILD_VOICE_STATES', 'GUILD_MEMBERS'] } });
额外补充修复
你当前代码没有导入ytdl-core依赖,直接使用了ytdl变量,会导致后续执行报错,需要在文件顶部添加导入语句:
const ytdl = require('ytdl-core');
内容的提问来源于stack exchange,提问作者user15011471
相关产品推荐
相关产品推荐

