
本文详解 discord 机器人添加角色时常见的权限错误(httpexception 400/50013),重点说明问题根源在于机器人的角色位置而非用户权限,并提供完整、安全、可复用的解决方案。
本文详解 discord 机器人添加角色时常见的权限错误(httpexception 400/50013),重点说明问题根源在于机器人的角色位置而非用户权限,并提供完整、安全、可复用的解决方案。
在 Discord 中,Missing Permissions (error code 50013) 错误绝非源于命令调用者(如服务器管理员)的权限不足,而是明确指向机器人自身缺乏操作目标角色的权限。根本原因在于 Discord 的角色层级(Role Hierarchy)机制:机器人只能管理位于其自身角色之下的角色,且只能向成员添加不高于自身最高角色的位置的角色。
你的原始代码存在多个关键问题:
- 角色位置设置时机错误:role.edit(position=10) 在角色创建前就尝试调用(若角色不存在,role 为 None,导致 AttributeError);
- add_roles() 参数顺序错误:user.add_roles(person, role) 实际是试图给命令发送者(user)添加 person 和 role —— 完全颠倒了目标对象;
- 未校验目标成员是否存在:discord.utils.get(..., name=person) 仅匹配昵称(nick)或全局用户名(username),且不支持 ID 或 mention,极易失败;
- 忽略机器人权限检查与错误处理:未提前验证机器人是否具备 manage_roles 权限,也未捕获常见异常。
✅ 正确做法如下(推荐使用 MemberConverter 自动解析成员 + 显式权限校验):
from discord.ext import commands
import discord
@bot.command(name="giverole")
@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)
# 若角色不存在,则创建(需机器人有 manage_roles 权限)
if not role:
try:
role = await ctx.guild.create_role(
name=role_name,
color=discord.Color(0x000000),
reason=f"由 {ctx.author} 创建,用于 giverole 命令"
)
# 将新角色置于合适位置(低于机器人的最高角色)
bot_top_role = ctx.guild.me.top_role
await role.edit(position=bot_top_role.position - 1 if bot_top_role.position > 1 else 1)
except discord.Forbidden:
return await ctx.send("❌ 无法创建角色:机器人缺少 `manage_roles` 权限。请检查角色层级!")
# 关键校验:确保机器人能管理该角色(位置 + 权限)
if role >= ctx.guild.me.top_role:
return await ctx.send(f"❌ 无法分配 `{role.name}`:该角色位置高于或等于机器人的最高角色,请将机器人角色拖至更高位置。")
# 执行加角色(目标是 member,不是 ctx.author)
try:
await member.add_roles(role, reason=f"由 {ctx.author} 通过 !giverole 分配")
await ctx.send(f"✅ 已成功为 {member.mention} 添加角色 `{role.name}`")
except discord.Forbidden:
await ctx.send("❌ 机器人缺少 `manage_roles` 权限,或目标角色位置过高。")
except discord.HTTPException as e:
await ctx.send(f"❌ 操作失败:{e}")? 重要注意事项:
- 永远不要“忽略用户权限”:Discord API 强制执行权限模型,这是安全底线。你真正需要做的是提升机器人的角色位置(在服务器设置 → 角色列表中,将机器人角色拖到所有可分配角色的上方);
- 使用 member: discord.Member 参数类型自动支持 @提及、ID、用户名等多种输入方式,比手动 utils.get() 更健壮;
- ctx.guild.me.top_role 是判断机器人角色层级的唯一可靠依据;
- 所有涉及角色编辑的操作(创建、改位置、加角色)均需机器人拥有 manage_roles 权限,且目标角色必须在其角色之下;
- 生产环境务必添加 @commands.bot_has_permissions(manage_roles=True) 检查,避免静默失败。
通过以上重构,你的命令将稳定、安全、符合 Discord 最佳实践 —— 不是绕过权限,而是正确配置权限与层级。

















