
本文详解 discord bot 添加角色时因角色层级限制导致的 50013 权限错误,重点说明机器人自身权限与角色位置的关系,并提供正确实现方式及最佳实践。
本文详解 discord bot 添加角色时因角色层级限制导致的 50013 权限错误,重点说明机器人自身权限与角色位置的关系,并提供正确实现方式及最佳实践。
在 Discord 中,Missing Permissions (error code: 50013) 错误并非源于命令调用者(如服务器管理员)的权限不足,而是机器人自身缺乏操作目标角色的权限。根本原因在于 Discord 的角色层级(Role Hierarchy)机制:机器人只能管理位于其自身角色之下的角色,且无法将高于自身的角色分配给成员。
你的原始代码存在多个关键问题:
- await user.add_roles(person, role) 逻辑错误:add_roles() 是 Member 对象的方法,应调用 person.add_roles(role),而非 user.add_roles(...);
- 角色创建与编辑顺序错误:role = discord.utils.get(...) 在角色尚未创建时返回 None,后续 role.edit() 会引发 AttributeError;
- 忽略机器人权限前提:即使你作为服务器所有者拥有全部权限,若机器人的角色在目标角色下方,仍会触发 50013 错误;
- 未处理用户查找失败情况:discord.utils.get(..., name=person) 仅匹配昵称(非用户名/ID),且不支持模糊匹配,极易返回 None。
✅ 正确做法如下:
✅ 1. 确保机器人具备必要权限
- 在 Discord 开发者门户为机器人启用 Manage Roles 权限;
- 在服务器中,将机器人的角色拖拽至目标角色上方(层级更高),这是硬性要求,无法绕过或“忽略”。
✅ 2. 修复代码逻辑(完整可运行示例)
import discord
from discord.ext import commands
@bot.command()
@commands.has_permissions(manage_roles=True) # 可选:限制仅管理员可用
async def giverole(ctx, member: discord.Member, role_name: str):
# 获取目标角色(支持名称匹配)
role = discord.utils.get(ctx.guild.roles, name=role_name)
# 若角色不存在,则创建(注意:需确保 bot 有 manage_roles 权限)
if role is None:
try:
role = await ctx.guild.create_role(
name=role_name,
color=discord.Color(0x000000),
reason=f"Created by {ctx.author} via !giverole"
)
# 创建后需手动将角色置于合适层级(bot 角色之下、目标成员之上)
# 注意:edit(position=...) 已弃用,改用 move_to() 或调整角色列表顺序
# 更稳妥做法:创建后通过 UI 或 move_to 调整位置(见下方说明)
except discord.Forbidden:
return await ctx.send("❌ 无法创建角色:机器人缺少 `Manage Roles` 权限。")
# 检查 bot 是否有权管理该角色(关键!)
if role.position >= ctx.guild.me.top_role.position:
return await ctx.send(f"❌ 无法分配角色 `{role.name}`:该角色层级高于或等于机器人的最高角色,请将机器人角色拖至其上方。")
# 执行加角色
try:
await member.add_roles(role, reason=f"Assigned by {ctx.author}")
await ctx.send(f"✅ 已为 {member.mention} 添加角色 `{role.name}`")
except discord.Forbidden:
await ctx.send("❌ 机器人缺少管理该成员或角色的权限。")
except discord.HTTPException as e:
await ctx.send(f"❌ 操作失败:{e}")⚠️ 重要注意事项
- 角色层级不可绕过:Discord API 强制校验 bot_role.position > target_role.position,这是安全机制,不存在“忽略用户权限”的合法方式;
- 推荐使用 Member 类型注解:替代 name 字符串查找,避免匹配失败(支持 @提及、ID、用户名);
- position 参数已弃用:新版 Discord API 使用 move_to() 或通过 Discord 客户端拖拽调整角色顺序;
- 始终检查 ctx.guild.me.top_role.position:这是判断机器人能否操作某角色的唯一可靠依据;
- 添加 reason 参数:便于审计日志追踪操作来源。
✅ 最佳实践总结
| 项目 | 推荐做法 |
|---|---|
| 权限配置 | 在 OAuth2 URL 中勾选 manage_roles;服务器中将 bot 角色置顶(或至少高于所有需管理的角色) |
| 用户识别 | 使用 member: discord.Member 参数类型,支持提及、ID、用户名自动解析 |
| 错误处理 | 显式捕获 Forbidden 和 HTTPException,给出清晰提示 |
| 安全性 | 添加 @commands.has_permissions(manage_roles=True) 防止普通用户滥用 |
只要机器人角色层级足够高、权限配置正确,该命令即可稳定运行——这不是代码缺陷,而是 Discord 安全模型的必然约束。

















