You need to enable JavaScript to run this app. Discord机器人踢/ban报403权限错误,@has_permissions装饰器失效
优惠活动
大模型
产品
解决方案
定价
更多

Discord机器人踢/ban报403权限错误,@has_permissions装饰器失效

踢人/封禁指令报403权限缺失的解决方法

这个报错是Discord API判定机器人本身没有执行对应操作的权限,和你作为服务器所有者的个人权限无关,常见触发原因为:

  • 角色层级优先级问题:Discord核心规则为「仅能操作角色层级低于自身的成员」。哪怕机器人绑定了全权限的管理员角色,如果该角色在服务器角色列表中的排序位置低于被操作用户的角色,依然会直接被拦截报权限缺失。解决方式:将机器人的专属角色拖动到服务器角色列表的最顶端区域,确保其层级高于所有普通成员、非管理类角色。
  • 权限被全局/频道级配置覆盖:如果服务器的「成员权限」全局设置里禁用了「踢除成员」「封禁成员」,或是在执行指令的频道权限设置中单独给机器人关闭了这两个权限,这类配置会优先覆盖角色层面给机器人配置的权限。
  • 邀请流程的权限授权问题:如果当初邀请机器人进服务器时,OAuth2授权页面没有勾选对应的操作权限范围,哪怕后续在后台给角色配置了全权限,机器人实际从API拿到的权限依然是邀请时授权的最小集合,需要重新通过带管理员权限的邀请链接拉机器人进服务器,覆盖原有权限配置。

快速排查工具

可在代码中临时加入一段指令,直接打印机器人当前的实际权限和角色层级,不用反复手动核对后台设置:

@client.command()
async def check_my_perm(ctx):
    bot_perms = ctx.guild.me.guild_permissions
    await ctx.send(
        f"机器人当前生效权限:\n"
        f"踢人权限:{bot_perms.kick_members}\n"
        f"封禁权限:{bot_perms.ban_members}\n"
        f"管理员权限:{bot_perms.administrator}\n"
        f"机器人最高角色排序位置:{ctx.guild.me.top_role.position}\n"
        f"你的最高角色排序位置:{ctx.author.top_role.position}"
    )

运行该指令即可看到机器人实际生效的权限值,定位配置错误的位置。


实现「拥有管理员 或 对应操作权限即可执行指令」的校验逻辑

discord.py内置的@commands.has_permissions()装饰器默认校验所有列出的权限,无法直接实现“或”的逻辑,需要编写自定义权限校验器:

自定义校验器实现

  • 对应kick指令:只要用户拥有administrator 或 kick_members 任意一个权限,即可执行指令
def can_kick():
    async def check_perm(ctx):
        # 两个条件满足任意一个即通过校验
        return ctx.author.guild_permissions.administrator or ctx.author.guild_permissions.kick_members
    return commands.check(check_perm)
  • 对应ban指令:只要用户拥有administrator 或 ban_members 任意一个权限,即可执行指令
def can_ban():
    async def check_perm(ctx):
        return ctx.author.guild_permissions.administrator or ctx.author.guild_permissions.ban_members
    return commands.check(check_perm)

指令替换示例

将原来指令上挂载的内置权限装饰器,替换为自定义校验器,同时补上之前代码中缺失的参数空值校验,避免无目标用户时报错:

@client.command()
@can_kick() # 替换原来的 @commands.has_permissions(administrator=True)
async def kick(ctx, user: discord.Member = None, *, reason="No reason provided"):
    # 空值判断
    if not user:
        await ctx.send("请指定要踢除的服务器成员")
        return
    # 禁止操作机器人自身
    if user == ctx.guild.me:
        await ctx.send("我无法踢除自己")
        return
    # 禁止操作层级与自己同级/更高的用户
    if user.top_role >= ctx.author.top_role and not ctx.author.guild_permissions.administrator:
        await ctx.send("你没有权限操作层级和你相同或更高的成员")
        return
    await user.kick(reason=reason)
    await ctx.send(f"已将 {user.mention} 移出服务器,操作理由:{reason}")


@client.command()
@can_ban() # 替换原来的 @commands.has_permissions(administrator=True)
async def ban(ctx, user: discord.Member = None, *, reason="No reason provided"):
    if not user:
        await ctx.send("请指定要封禁的服务器成员")
        return
    if user == ctx.guild.me:
        await ctx.send("我无法封禁自己")
        return
    if user.top_role >= ctx.author.top_role and not ctx.author.guild_permissions.administrator:
        await ctx.send("你没有权限操作层级和你相同或更高的成员")
        return
    await user.ban(reason=reason)
    await ctx.send(f"已将 {user.mention} 封禁,操作理由:{reason}")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.02 22:15:04