discord.js v12中guild.member.hasPermission调用报错问题
报错产生原因
这是discord.js v11升级到v12的破坏性变更导致的,具体有两点:
- v11版本中
Guild实例上的member属性,用于直接获取机器人自身在当前服务器的成员对象,该属性在v12版本中被完全移除,直接访问guild.member会得到undefined,后续链式调用hasPermission方法自然会抛出「不是函数」的错误。 - 现有代码还存在额外逻辑漏洞:查找目标服务器时硬编码了id为
'000000000',后续拉取角色时又用环境变量里的env.GUILD_ID查询缓存,两个id不匹配时会出现找不到目标服务器、重复查询缓存的问题。
修复方案
不需要将权限校验逻辑移出ready事件——ready事件触发时客户端已经完成所有服务器基础资源的缓存初始化,相关属性可以直接访问,不需要等待其他事件触发。直接按v12的API规范修改对应代码即可:
- 统一目标服务器的获取逻辑,直接用环境变量中的
GUILD_ID从缓存取服务器实例,去掉硬编码的测试id。 - v12版本提供了
guild.me属性,可直接获取机器人在当前服务器的GuildMember实例,替换掉已废弃的guild.member写法即可。 - 后续拉取角色的逻辑可以直接复用前面拿到的
guild实例,减少不必要的缓存查询。
修复后的完整代码如下:
client.on('ready', async () => { log.success(`Authenticated as ${client.user.tag}`); client.user.setPresence({ activity: { name: env.PRESENCE_ACTIVITY, type: env.PRESENCE_TYPE.toUpperCase(), }, }); const guild = client.guilds.cache.get(env.GUILD_ID); if (!guild) return console.log(`Can't find any guild with the ID "${env.GUILD_ID}"`); if (guild.me.hasPermission('ADMINISTRATOR', false)) { log.success("Bot has the 'ADMINISTRATOR' permission"); } else { log.warn("Bot does not have 'ADMINISTRATOR' permission"); } guild.roles.fetch() .then((roles) => { goodieRole = roles.cache.get(env.GOODIE_ROLE_ID); }); });
注意:如果后续升级到v13及以上版本,
hasPermission方法会被进一步废弃,需要替换为permissions.has()写法,当前修复方案完全适配v12版本,可直接运行。
内容的提问来源于stack exchange,提问作者Eli
相关产品推荐
相关产品推荐

