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

使用discord.py时已拥有指定角色却触发MissingRole异常

问题解决:discord.py has_role装饰器检测角色ID失败

问题原因

commands.has_role()装饰器的参数如果是字符串类型的角色ID,会被当作角色名称去匹配,而非角色ID。你的env.METACORE_MODERATOR_ROLE_ID大概率是字符串格式,导致装饰器检查时找不到对应名称的角色(角色名称不可能是一串纯数字),因此抛出MissingRole异常——即便你实际拥有该ID对应的角色。

解决方案

方案1:将角色ID转为整数传入装饰器

直接在装饰器里把环境变量的字符串ID转为整数:

@commands.command(name='create-embed')
@commands.has_role(int(env.METACORE_MODERATOR_ROLE_ID))  # 转为整数类型
async def create_embed(self, ctx: commands.Context):
    # 原有代码逻辑不变
    embed_title = 'Test title'
    view = embed.view.CreateEmbedView()
    view.bot = self.bot
    view.author_id = ctx.author.id
    result_embed = discord.Embed(title=embed_title)
    embed_message = await ctx.send(embed=result_embed, view=view, ephemeral=True)
    view.embed = result_embed
    view.embed_message = embed_message

方案2:自定义检查器(更稳定)

如果担心类型问题,可使用@commands.check自定义检查逻辑,手动验证用户是否拥有目标角色:

def has_moderator_role():
    async def predicate(ctx):
        # 转换角色ID为整数
        target_role_id = int(env.METACORE_MODERATOR_ROLE_ID)
        # 遍历用户角色列表匹配ID
        return any(role.id == target_role_id for role in ctx.author.roles)
    return commands.check(predicate)

# 在命令上使用自定义检查器
@commands.command(name='create-embed')
@has_moderator_role()
async def create_embed(self, ctx: commands.Context):
    # 原有代码逻辑不变

方案3:确保环境变量存储为整数类型

若使用.env文件管理配置,加载时直接将变量转为整数:

import os
from dotenv import load_dotenv

load_dotenv()
# 加载时直接转换类型
METACORE_MODERATOR_ROLE_ID = int(os.getenv("METACORE_MODERATOR_ROLE_ID"))

调试验证

可在命令开头添加调试代码,确认角色ID类型和用户角色列表:

async def create_embed(self, ctx: commands.Context):
    print(type(env.METACORE_MODERATOR_ROLE_ID))  # 输出应为<class 'int'>
    print([role.id for role in ctx.author.roles])  # 查看用户所有角色ID
    # 原有代码逻辑不变

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 03:46:02