Error with embed discord/Python

When using !status I get this following

**ERROR**
Traceback (most recent call last):
  File "/home/runner/some-bot/venv/lib/python3.10/site-packages/discord/ext/commands/core.py", line 235, in wrapped
    ret = await coro(*args, **kwargs)
  File "main.py", line 92, in status
    character = load_character(ctx.message.author.id)
  File "main.py", line 15, in load_character
    return Character(**db["characters"][str(user_id)])
  File "/home/runner/some-bot/venv/lib/python3.10/site-packages/replit/database/database.py", line 336, in __getitem__
    return self.value[k]
KeyError: '136206685319462913'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/runner/some-bot/venv/lib/python3.10/site-packages/discord/ext/commands/bot.py", line 1350, in invoke
    await ctx.command.invoke(ctx)
  File "/home/runner/some-bot/venv/lib/python3.10/site-packages/discord/ext/commands/core.py", line 1029, in invoke
    await injected(*ctx.args, **ctx.kwargs)  # type: ignore
  File "/home/runner/some-bot/venv/lib/python3.10/site-packages/discord/ext/commands/core.py", line 244, in wrapped
    raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: KeyError: '136206685319462913' 

Repl link:

import os, discord
from discord.ext import commands

from replit import db
from LRPG_Game import Character
from LRPG_Game import GameMode

DISCORD_TOKEN = os.getenv("DISCORD_TOKEN")
intents = discord.Intents.default()
intents.message_content = True
bot = commands.Bot(command_prefix="!",intents=intents)

# Helper functions
def load_character(user_id):
    return Character(**db["characters"][str(user_id)])

MODE_COLOR = {
    GameMode.BATTLE: 0xDC143C,
    GameMode.ADVENTURE: 0x005EB8,
}
def status_embed(ctx, character):

    # Current mode
    if character.mode == GameMode.BATTLE:
        mode_text = f"Currently battling a {character.battling.name}."
    elif character.mode == GameMode.ADVENTURE:
        mode_text = "Currently adventuring."

      # Create embed with description as current mode
    embed = discord.Embed(title=f"{character.name} status", description=mode_text, color=MODE_COLOR[character.mode])
    embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar_url)
  
      # Stats field
    _, xp_needed = character.ready_to_level_up()

    embed.add_field(name="Stats", value=f"""
    **HP:**    {character.hp}/{character.max_hp}
    **ATTACK:**   {character.attack}
    **DEFENSE:**   {character.defense}
    **MANA:**  {character.mana}
    **LEVEL:** {character.level}
    **XP:**    {character.xp}/{character.xp+xp_needed}
    """, inline=True)
      # Inventory field
    inventory_text = f"Gold: {character.gold}\n"
    if character.inventory:
        inventory_text += "\n".join(character.inventory)

    embed.add_field(name="Inventory", value=inventory_text, inline=True)
   
    return embed
@bot.event
async def on_ready():
    print(f"{bot.user} has connected to Discord!")
  
# Commands
@bot.command(name="create", help="Create a character.")
async def create(ctx, name=None):
    user_id = ctx.message.author.id

    # if no name is specified, use the creator's nickname
    if not name:
        name = ctx.message.author.name
        # create characters dictionary if it does not exist
    if "characters" not in db.keys():
        db["characters"] = {}

    # only create a new character if the user does not already have one
    if user_id not in db["characters"] or not db["characters"][user_id]:
        character = Character(**{
            "name": name,
            "hp": 16,
            "max_hp": 16,
            "attack": 2,
            "defense": 1,
            "mana": 0,
            "level": 1,
            "xp": 0,
            "gold": 0,
            "inventory": [],
            "mode": GameMode.ADVENTURE,
            "battling": None,
            "user_id": user_id
        })
        character.save_to_db()
        await ctx.message.reply(f"New level 1 character created: {name}. Enter `!status` to see your stats.")
    else:
        await ctx.message.reply("You have already created your character.")

@bot.command(name="status", help="Get information about your character.")
async def status(ctx):
  character = load_character(ctx.message.author.id)

  embed = status_embed(ctx, character)
  await ctx.message.reply(embed=embed)
  
bot.run(DISCORD_TOKEN)

I was just following the tutorial but for whatever reason this doesn’t work as the tutorial intended.

The error is telling you that this user ID doesn’t exist in the characters key of your database.
You need to check if the user_id exists in your database before trying to load it.

You can change this:

To this:

def load_character(user_id):
    user_id_str = str(user_id)
    if "characters" in db and user_id_str in db["characters"]:
        return Character(**db["characters"][user_id_str])
    else:
        return None

And after that you check if the char was loaded ok. You can achiev this by modyfing the status:

Just make a simple check like:

@bot.command(name="status", help="Get information about your character.")
async def status(ctx):
    character = load_character(ctx.message.author.id)
    if character:
        embed = status_embed(ctx, character)
        await ctx.message.reply(embed=embed)
    else:
        await ctx.message.reply("Insert the message that you want in case that the char does not exist.")
2 Likes

Thank you! That helps with the error function.

I am getting a different type of issue now, in regards that I don’t think my create character function is saving the character correctly.

As the results when I use !create and then !status results in the message “Insert the message that you want in case that the char does not exist.”, which implies that the !create function is not actually saving the character correctly. So I will look into that.

But thank you again for helping me fix the error!

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.