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

Discord Bot命令转hybrid command报回调非协程错误排查

Discord.py 混合命令报「回调必须是协程」修复方案

报错核心原因

你在命令函数上同时叠加了@commands.hybrid_command和@app_commands.command()两个装饰器,属于写法错误:

  • 装饰器执行顺序为从下往上,@app_commands.command()会先把原本的协程函数包装成应用命令对象,这个对象本身不是协程。外层的@commands.hybrid_command拿到这个非协程对象做合法性校验时,就会直接抛出「the callback must be a coroutine」错误。
  • @commands.hybrid_command本身就会同时注册前缀普通命令、斜杠应用命令,不需要额外再加@app_commands.command()装饰器。

另外你的代码还有两处隐性问题:

  1. hybrid命令第一个入参要求是commands.Context类型,你写的discord.Interaction不符合签名规范,会导致前缀命令触发时参数解析错误。
  2. main.py的__init__方法中,你提前配置了开启message_content权限的intents,但传给父类构造函数时又新建了一个discord.Intents.all(),之前的配置没有生效;setup_hook里同步命令树用了全局变量bot,类内部应该用self指代实例,会触发变量未定义错误。

修复方案

  1. 删除help命令上多余的@app_commands.command()装饰器
  2. 修正hybrid命令的入参签名,适配两种调用方式的响应逻辑
  3. 修正main.py里的intents传参、tree.sync调用对象错误

修复后 main.py 代码

class MyBot(commands.Bot):

    def __init__(self):
        intents=discord.Intents.all()
        intents.message_content = True

        super().__init__(
            command_prefix='!',
            intents=intents # 传入提前配置好权限的intents
        )

        self.initial_extensions = [
            "cogs.user_commands"
        ]


    async def setup_hook(self):
        for ext in self.initial_extensions:
            await self.load_extension(ext)
        # 类内部用self指代当前bot实例
        await self.tree.sync(guild = discord.Object(id=191453821174531128))

修复后 cogs/user_commands.py 代码

from typing import Optional, List
import discord
from discord import app_commands
from discord.ext import commands

class user_commands(commands.Cog):

    def __init__(self, bot):
        self.bot = bot
        bot.remove_command("help")

    @commands.hybrid_command(name='help', with_app_command=True, description='查看命令帮助')
    async def help(self, ctx: commands.Context, command: Optional[str]):
        # 原有embed生成逻辑保留
        ......

        # 兼容两种触发方式的响应逻辑
        if ctx.interaction:
            # 斜杠触发时返回临时消息
            await ctx.send(embed=embed, ephemeral=True)
        else:
            # 前缀命令触发时返回普通频道消息
            await ctx.send(embed=embed)

    @help.autocomplete('command')
    async def help_autocomplete(self,
        interaction: discord.Interaction,
        current: str,
    ) -> List[app_commands.Choice[str]]:
        # 原有自动补全逻辑保留
        .....

补充注意

  • 如果你需要给hybrid命令的斜杠版本添加参数说明,可以直接用@app_commands.describe()装饰器,不要重复叠加@app_commands.command()。
  • 写完修改后重启bot,第一次同步斜杠命令可能需要1-2分钟生效,测试时不要频繁调用sync接口避免触发接口限流。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 22:09:15