Rapptz / discord.py

An API wrapper for Discord written in Python.
http://discordpy.rtfd.org/en/latest
MIT License
14.86k stars 3.76k forks source link

discord.py bug on await member.edit() function. #9839

Closed Allowwed closed 5 months ago

Allowwed commented 5 months ago

Summary

Error on changing/reseting nickname.

Reproduction Steps

My nick command used to work fine but I don't know why I am getting this error today.

Minimal Reproducible Code

0|bot  | Traceback (most recent call last):
0|bot  |   File "/path/to/venv/lib/python3.11/site-packages/discord/client.py", line 441, in _run_event
0|bot  |     await coro(*args, **kwargs)
0|bot  |   File "/root/core/errors.py", line 130, in on_command_error
0|bot  |     raise error
0|bot  |   File "/path/to/venv/lib/python3.11/site-packages/discord/ext/commands/core.py", line 235, in wrapped
0|bot  |     ret = await coro(*args, **kwargs)
0|bot  |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
0|bot  |   File "/root/cogs/moderation.py", line 665, in nick
0|bot  |     await member.edit(nick=nick)
0|bot  |   File "/path/to/venv/lib/python3.11/site-packages/discord/member.py", line 914, in edit
0|bot  |     return Member(data=data, guild=self.guild, state=self._state)
0|bot  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
0|bot  |   File "/path/to/venv/lib/python3.11/site-packages/discord/member.py", line 348, in __init__
0|bot  |     self._user: User = state.store_user(data['user'])
0|bot  |                                         ~~~~^^^^^^^^
0|bot  | TypeError: string indices must be integers, not 'str'
@commands.command()
async def nick(self, ctx: Context, member: discord.Member, nick: str = None):
    await member.edit(nick=nick)
    await ctx.send("Done!")

Expected Results

I expected it to changed the nickname or remove the nickname without any error.

Actual Results

I get the following error:

0|bot  | Traceback (most recent call last):
0|bot  |   File "/path/to/venv/lib/python3.11/site-packages/discord/client.py", line 441, in _run_event
0|bot  |     await coro(*args, **kwargs)
0|bot  |   File "/root/core/errors.py", line 130, in on_command_error
0|bot  |     raise error
0|bot  |   File "/path/to/venv/lib/python3.11/site-packages/discord/ext/commands/core.py", line 235, in wrapped
0|bot  |     ret = await coro(*args, **kwargs)
0|bot  |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
0|bot  |   File "/root/cogs/moderation.py", line 665, in nick
0|bot  |     await member.edit(nick=nick)
0|bot  |   File "/path/to/venv/lib/python3.11/site-packages/discord/member.py", line 914, in edit
0|bot  |     return Member(data=data, guild=self.guild, state=self._state)
0|bot  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
0|bot  |   File "/path/to/venv/lib/python3.11/site-packages/discord/member.py", line 348, in __init__
0|bot  |     self._user: User = state.store_user(data['user'])
0|bot  |                                         ~~~~^^^^^^^^
0|bot  | TypeError: string indices must be integers, not 'str'

However the nickname changes without any issue, but I am not able to send the confirmation message as it stops the command execution.

Intents

message, guilds, members

System Information

Name: discord.py Version: 2.3.2 Summary: A Python wrapper for the Discord API Home-page: https://github.com/Rapptz/discord.py Author: Rapptz Author-email: License: MIT Location: /usr/lib/python3/dist-packages Requires: Required-by:

Python 3.11.6

Checklist

Additional Context

No response

MCausc78 commented 5 months ago

Please put following code before bot.run or in command:

import logging

logging.getLogger('discord.http').setLevel(logging.DEBUG)

And send discord.http logs

AbstractUmbra commented 5 months ago

Hi,

I cannot reproduce this error within the v2.3.2 release/tag of discord.py.

I'm using the following code to test:-

Codeblock ```py import logging import discord from discord.ext import commands bot = commands.Bot(command_prefix=">>!", intents=discord.Intents.all()) @bot.command() async def nick( ctx: commands.Context, member: discord.Member, nick: str | None = None ) -> None: version = discord.version_info await ctx.send(f"Version info: {version}") await member.edit(nick=nick) # no return with these parameters mem = ctx.guild.get_member(member.id) # fresh from cache await ctx.send(f"Member new nick: {mem.nick}") bot.run( "...", log_level=logging.DEBUG, ) ```

There were no errors output in my console, nor present from what I could see. I got the following debug logging output:-

Logs editing another member ``` 2024-05-20 13:46:57 DEBUG discord.http POST https://discord.com/api/v10/channels/1231613037568589827/messages with {"content":"Member new nick: test","components":[],"tts":false} has returned 200 2024-05-20 13:46:57 DEBUG discord.http POST https://discord.com/api/v10/channels/1231613037568589827/messages has received {'type': 0, 'channel_id': '1231613037568589827', 'content': 'Member new nick: test', 'attachments': [], 'embeds': [], 'timestamp': '2024-05-20T12:46:56.989000+00:00', 'edited_timestamp': None, 'flags': 0, 'components': [], 'id': '1242096224652361783', 'author': {'id': '1242095921798316032', 'username': "Link's Test Bot", 'avatar': None, 'discriminator': '5322', 'public_flags': 0, 'flags': 0, 'bot': True, 'banner': None, 'accent_color': None, 'global_name': None, 'avatar_decoration_data': None, 'banner_color': None, 'clan': None}, 'mentions': [], 'mention_roles': [], 'pinned': False, 'mention_everyone': False, 'tts': False, 'referenced_message': None} ```

I also tried on an upwards member in the hierarchy which errored as expected:

Logs for upward hierarchy ``` 2024-05-20 13:56:23 DEBUG discord.http PATCH https://discord.com/api/v10/guilds/1231613037568589824/members/565095015874035742 with {"nick":"Mipha"} has returned 403 2024-05-20 13:56:23 DEBUG discord.client Dispatching event command_error 2024-05-20 13:56:23 ERROR discord.ext.commands.bot Ignoring exception in command nick Traceback (most recent call last): File "/home/penumbra/projects/other/test/.venv/lib/python3.12/site-packages/discord/ext/commands/core.py", line 235, in wrapped ret = await coro(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/penumbra/projects/other/test/bot.py", line 16, in nick await member.edit(nick=nick) # no return with these parameters ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/penumbra/projects/other/test/.venv/lib/python3.12/site-packages/discord/member.py", line 913, in edit data = await http.edit_member(guild_id, self.id, reason=reason, **payload) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/penumbra/projects/other/test/.venv/lib/python3.12/site-packages/discord/http.py", line 739, in request raise Forbidden(response, data) discord.errors.Forbidden: 403 Forbidden (error code: 50013): Missing Permissions The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/home/penumbra/projects/other/test/.venv/lib/python3.12/site-packages/discord/ext/commands/bot.py", line 1350, in invoke await ctx.command.invoke(ctx) File "/home/penumbra/projects/other/test/.venv/lib/python3.12/site-packages/discord/ext/commands/core.py", line 1029, in invoke await injected(*ctx.args, **ctx.kwargs) # type: ignore ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/penumbra/projects/other/test/.venv/lib/python3.12/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: Forbidden: 403 Forbidden (error code: 50013): Missing Permissions ```

So I'm at a loss for reproducing this error. Could you give more context to this, did you try and change the bot's nickname, someone else in the guild's nickname, and their hierarchical ordering compared to the bot itself within the guild?

Allowwed commented 5 months ago

Please put following code before bot.run or in command:

import logging

logging.getLogger('discord.http').setLevel(logging.DEBUG)

And send discord.http logs

0|bot  | [2024-05-20 18:19:02] [DEBUG   ] discord.http: PATCH http://localhost:3000/api/guilds/1117047696595898420/members/1109080079797071963 with {"nick":""} has returned 204
0|bot  | [2024-05-20 18:19:02] [DEBUG   ] discord.http: PATCH /guilds/{guild_id}/members/{user_id} has found its initial rate limit bucket hash (c7f060a5d9790cb6f53000110a7b7edf).
0|bot  | [2024-05-20 18:19:02] [DEBUG   ] discord.http: PATCH http://localhost:3000/api/guilds/1117047696595898420/members/1109080079797071963 has received 
0|bot  | [2024-05-20 18:19:02] [DEBUG   ] discord.http: PUT http://localhost:3000/api/channels/1240599615649091596/messages/1242096750274150474/reactions/%3Aalert_blaze%3A1226481315214528573/@me with None has returned 204
0|bot  | [2024-05-20 18:19:02] [DEBUG   ] discord.http: PUT /channels/{channel_id}/messages/{message_id}/reactions/{emoji}/@me has found its initial rate limit bucket hash (acca06189c86c292e9013a444ec3184d).
0|bot  | [2024-05-20 18:19:02] [DEBUG   ] discord.http: A rate limit bucket (acca06189c86c292e9013a444ec3184d) has been exhausted. Pre-emptively rate limiting...
0|bot  | [2024-05-20 18:19:02] [DEBUG   ] discord.http: PUT http://localhost:3000/api/channels/1240599615649091596/messages/1242096750274150474/reactions/%3Aalert_blaze%3A1226481315214528573/@me has received 
0|bot  | [2024-05-20 18:19:03] [ERROR   ] discord.client: Ignoring exception in on_command_error
0|bot  | Traceback (most recent call last):
0|bot  |   File "/usr/local/lib/python3.11/dist-packages/discord/client.py", line 441, in _run_event
0|bot  |     await coro(*args, **kwargs)
0|bot  |   File "/root/core/errors.py", line 130, in on_command_error
0|bot  |     raise error
0|bot  |   File "/usr/local/lib/python3.11/dist-packages/discord/ext/commands/core.py", line 235, in wrapped
0|bot  |     ret = await coro(*args, **kwargs)
0|bot  |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
0|bot  |   File "/root/cogs/moderation.py", line 665, in nick
0|bot  |     await member.edit(nick=nick)
0|bot  |   File "/usr/local/lib/python3.11/dist-packages/discord/member.py", line 914, in edit
0|bot  |     return Member(data=data, guild=self.guild, state=self._state)
0|bot  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
0|bot  |   File "/usr/local/lib/python3.11/dist-packages/discord/member.py", line 348, in __init__
0|bot  |     self._user: User = state.store_user(data['user'])
0|bot  |                                         ~~~~^^^^^^^^
0|bot  | TypeError: string indices must be integers, not 'str'

I don't get this error on my test bot

AbstractUmbra commented 5 months ago

I can see in your debug logging that your HTTP requests are going to http://localhost:3000/. Are you operating a proxy between discord.py and discord?

Allowwed commented 5 months ago

I found that this error is causing for using https://github.com/twilight-rs/http-proxy and when i don't use it it works fine.

Allowwed commented 5 months ago

I can see in your debug logging that your HTTP requests are going to http://localhost:3000/. Are you operating a proxy between discord.py and discord?

Yeah.

AbstractUmbra commented 5 months ago

Historically we've had issues when users use the Twilight proxy, and it is outside of our scope for assistance. You'll need to raise this with the proxy developers and let them resolve the issue you're experiencing, as discord.py works as intended.

Allowwed commented 5 months ago

Historically we've had issues when users use the Twilight proxy, and it is outside of our scope for assistance. You'll need to raise this with the proxy developers and let them resolve the issue you're experiencing, as discord.py works as intended.

Okay, thank you.

Rapptz commented 5 months ago

For future visitors, the reason why this most likely failed is because the proxy URL did not have an explicit version set. The library assumes v10 of the Discord API, while the default unqualified version is v6. Therefore it manifests into these errors.