0
votes

I'm very confused at how this error is occurring, it is only occurring when I use the kick/ban command in my bot and no other commands, I looked in the on_message function and it doesn't cause an error when I message anything else except from the kick/ban command and I'm not sure why. I am passing in guild correctly and there is an id attribute because the code is still working but it comes up with this anyway.

Here's the error:

    Ignoring exception in on_message
Traceback (most recent call last):
  File ".local/lib/python3.7/site-packages/discord/client.py", line 333, in _run_event
    await coro(*args, **kwargs)
  File "file path", line 1937, in on_message
    await open_automod(guild)
  File "file path", line 1920, in open_automod
    if str(guild.id) in data:
AttributeError: 'NoneType' object has no attribute 'id'

Here's an example of a bot command that causes this error:

@bot.command(name='testlog')
@commands.has_permissions(kick_members=True)
async def kick (ctx, member:discord.Member, *reason):
    moderator = ctx.message.author.id
    server = ctx.guild.id
    if member == None or member == moderator:
        await ctx.channel.send("You cannot kick yourself")
        return
    if reason == None:
        reason = "no reason stated"
    reason = " ".join(reason)
    message = f"You have been banned from {ctx.guild.name}. Reason: {reason}"
    await member.send(message)
    await ctx.channel.send(f"{member} has been kicked. Reason: {reason}")
    await send_log('test', moderator, member.id, reason, server)

Here's the open_automod function:

async def open_automod(guild):
    data = await get_automod_data()

    if str(guild.id) in data:
        return False
    else:
        data[str(guild.id)] = {}
        data[str(guild.id)]["automodenabled"] = f'off'
        data[str(guild.id)]["automodlogging"] = f'false'
        data[str(guild.id)]["automodchannel"] = 0

    with open("automoderator.json","w") as f:
        json.dump(data,f)
    return True

Here's the section of the code that is passing in 'guild':

@bot.event
async def on_message(message):  
    guild = message.guild
    await open_automod(guild)

What I don't get is why this error only shows up on the message where im using kicks or bans or in the above case a test kick. Could anyone explain why i'm getting this error and why it only happens on this message? An example of the message would be 'h/testlog @user reason'

1
if the message is sent in dm's the guild will be None - Łukasz Kwieciński

1 Answers

1
votes
  1. Looks like on_message is being run instead of kick as the error shows. From your questions it looks like you are expecting kick to be run. This is because of overriding on_message. See discord.py documentation for Why does on_message make my commands stop working?:

Overriding the default provided on_message forbids any extra commands from running. To fix this, add a bot.process_commands(message) line at the end of your on_message. Alternatively, you can place your on_message logic into a listener [with @bot.listen('on_message')]

  1. From the error message it's quite clear that guild is None. Discord.py docs do show that Message.guild is optional. So you should guard against that:
@bot.event
async def on_message(message):  
    if (guild := message.guild):
        await open_automod(guild)
  1. However, it again looks like you're expecting guild to have a value in both kick and on_message, so you should figure out why it doesn't. My guess is you're sending our testlog message/command directly to the bot and not in a guild channel - therefore the bot doesn't know what guild to target.
    • If the kick is meant to only be called within a channel, you should make sure to check that ctx.guild and ctx.channel are not None before attempting to use them and instead reply with instructions how to use the bot correctly.
    • If kick command is meant to be sent directly to the bot and not in a channel, you should figure out another way of getting the guild and channel (e.g. storing it, or passing as part of the command).