Trouble with python Discord bot (discord.ext.commands.bot: Ignoring exception in command None discord.ext.commands.errors.CommandNotFound)

Question:

I had to remake this bot lately and now it’s not working at all. It’s a level bot for Discord that auto assigns roles as you level up. I’m not sure if I’m overlooking something with the cogs?

I get this error whenever I run any command:

[2022-12-26 14:17:35] [ERROR ] discord.ext.commands.bot: Ignoring exception in command None
discord.ext.commands.errors.CommandNotFound: Command "rank" is not found

main.py

import discord
from discord.ext import commands
from private.config import token
import lvlsys

cogs = [lvlsys]

client = commands.Bot(command_prefix="+", intents=discord.Intents.all())

@client.event
async def on_ready():
    print("Bot is online!")
    await client.change_presence(activity=discord.Activity(type=discord.ActivityType.watching, name="yo mama"))

async def main():
    for i in range(len(cogs)):
        await cogs[i].setup(client)

client.run(token)

lvlsys.py

import discord
from discord.ext import commands, tasks
from pymongo import MongoClient
from discord.utils import get

# Channels
...
# Levels
...
# Database
...
# Commands

class lvlsys(commands.Cog):
    def __init__(self, client):
       self.client = client

    @commands.Cog.listener()
    async def on_message(self, message):
...

    @commands.command()
    async def rank(self, ctx):
...

    @commands.command()
    async def leaderboard(self, ctx):
...

    @commands.command()
    async def givexp(self, userID: int, addedxp: int, ctx):
...
                           

async def setup(client):
    await client.add_cog(lvlsys(client))

I’ve played around with the cogs but ultimately, nothing has worked.

Edit:
Importing asyncio, using setup_hook() and load_extension() in main.py, actually executing the main function and making sure client.run(token) is below the main function fixed the issue.

import discord
from discord.ext import commands
import os
import asyncio

client = commands.Bot(command_prefix="+", intents=discord.Intents.all())

@client.event
async def on_ready():
  print(f"Online.")

async def setup_hook():
  await client.load_extension("Cogs.lvlsys")
  
async def main():
  await setup_hook()
  
asyncio.run(main())
client.run(os.environ['token'])
Asked By: Yagi

||

Answers:

You load the Cogs in main, but you’re never actually calling that main function, so you’re never loading your extensions, so the Cog is never attached. Python doesn’t know that it first has to run your asynchronous main function before running the rest of the code…

setup_hook is the recommended place to do this sort of stuff in. If you don’t want to use it for whatever reason, you’ll have to start the bot using start instead of run instead, and start your main manually. See the link below for both (but just use setup_hook, it makes your life easier).

This is also not the greatest:

    for i in range(len(cogs)):
        await cogs[i].setup(client)

load_extension was invented for this very purpose. Don’t loop over a list of imports and manually call the setup method.

There’s a few examples on how to load cogs, one of them can be found in the migration guide: https://discordpy.readthedocs.io/en/stable/migrating.html#extension-and-cog-loading-unloading-is-now-asynchronous

This explains how to use setup_hook as well as manual async mains (but, again, just use setup_hook).

Also don’t call change_presence in on_ready, it can make Discord disconnect you. There’s really 0 reason to do it because you can just pass your presence info when you create the commands.Bot instance directly.

PS. if you’re looping over a list of items, just do for item in collection instead of indexing over range(len(collection))

Answered By: stijndcl
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.