You need to enable JavaScript to run this app. discord.ext.commands 报CommandNotFound:未找到自定义'rank'命令排查
优惠活动
大模型
产品
解决方案
定价
更多

discord.ext.commands 报CommandNotFound:未找到自定义'rank'命令排查

问题根因定位
  • 语法错误导致模块完全加载失败
    你贴的代码最后一行await ctx.channel.send(embed=embed)" 多了一个多余的双引号,会直接触发Python语法错误,整个包含rank命令的模块无法被正常导入,所有写在这个文件里的命令都不会被注册到Bot实例上。
  • 命令注册失败核心原因(对应代码第三行函数定义问题)
    你定义命令的函数签名是async def rank(self, ctx, rank):,存在两个会直接导致命令不被加载的错误:
    1. 如果这个函数是写在普通Python脚本(非Cog类结构)中,参数列表里多了self参数:discord.py在注册命令时会严格校验函数参数顺序,要求普通脚本的命令第一个参数必须是ctx,多余的位置参数会导致装饰器直接丢弃这个命令,不会将其加入Bot的命令列表,自然会触发CommandNotFound报错。
    2. 参数列表里多了一个必填位置参数rank:这个参数没有设置默认值,意味着用户直接调用!rank不带任何额外参数时,discord.py会判定为参数缺失,甚至在命令注册阶段因为参数逻辑校验不通过,直接拒绝加载这个命令。
  • 装饰器作用域问题(对应代码第二行装饰器问题)
    如果你是把这个命令写在Cog类结构中,却没有实现对应的Cog加载逻辑(比如没有写async def setup(bot): await bot.add_cog(你的Cog类(bot))的代码,也没有在Bot初始化时调用add_cog把类加进去),哪怕装饰器正常运行,对应的命令方法也不会被绑定到Bot实例上,依然会触发命令找不到的报错。
  • 局部变量命名冲突
    函数参数里定义了rank,后面计算排行榜位置的时候又重新赋值了rank = 0做计数变量,哪怕命令最终能正常加载,也会出现变量覆盖的逻辑错误。
  • 执行顺序错误
    刚进入函数就执行await ctx.send(rank),没有先判断当前频道是不是允许响应的bot_channel,会导致不管在哪个频道调用命令都会先发送无意义的内容。
  • 旧API兼容问题
    代码里使用的ctx.author.avatar_url是discord.py 1.x版本的写法,在2.x版本中已经替换为ctx.author.avatar.url,不做修改会触发属性不存在的报错。
修正后的可运行代码参考
bot_channel = 替换为你实际的bot专属频道ID
leveling = 你的MongoDB集合对象(和原逻辑保持一致即可)

@commands.command()
async def rank(ctx):
    # 先校验频道权限
    if ctx.channel.id != bot_channel:
        return
    # 查询用户等级数据
    stats = leveling.find_one({"id": ctx.author.id})
    if stats is None:
        embed = discord.Embed(description="You haven't sent any messages, no rank!!!")
        await ctx.channel.send(embed=embed)
        return
    # 计算等级和进度
    xp = stats["xp"]
    lvl = 0
    user_rank = 0
    while True:
        if xp < ((50*(lvl**2))+(50*lvl)):
            break
        lvl += 1
        xp -= (50 * (lvl - 1) ** 2) + (50 * (lvl - 1))
    boxes = int((xp/(200*((1/2) * lvl)))*20)
    # 计算用户全服排名
    rankings = leveling.find().sort("xp", -1)
    for x in rankings:
        user_rank += 1
        if stats["id"] == x["id"]:
            break
    # 构建嵌入消息
    embed = discord.Embed(title=f"{ctx.author.name}'s level stats")
    embed.add_field(name="Name", value=ctx.author.mention, inline=True)
    embed.add_field(name="XP", value=f"{xp}/{int(200*((1/2)*lvl))}", inline=True)
    embed.add_field(name="Rank", value=f"{user_rank}/{ctx.guild.member_count}", inline=True)
    embed.add_field(name="Progress Bar [lvl]", value=boxes * ":blue_square:" + (20-boxes) * ":white_large_square", inline=False)
    embed.set_thumbnail(url=ctx.author.avatar.url)
    await ctx.channel.send(embed=embed)

注意:如果你的代码是基于Cog结构开发的,保留函数参数里的self,去掉多余的rank参数即可,同时确保Cog被正常加载到Bot实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.29 11:06:04