TypeError: startswith first arg must be str or a tuple of str, not bytes
Closed this issue · 5 comments
Summary
TypeError: startswith first arg must be str or a tuple of str, not bytes
Reproduction Steps
Create webhook with a member's avatar url as the url
Minimal Reproducible Code
await channel.create_webhook(name="example name", avatar=member.avatar.url, reason="example reason")
Expected Results
I expected a webhook to be created
Actual Results
I received this exception:
Traceback (most recent call last):
File "C:\Users\rdtla\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\discord\ext\commands\core.py", line 179, in wrapped
ret = await coro(*args, **kwargs)
File "C:\Users\rdtla\OneDrive\Documents\GitHub\impersonator\cogs\impersonation.py", line 19, in _say_command
webhook: discord.Webhook = await channel.create_webhook(name="example name", avatar=member.avatar.url, reason="example reason")
File "C:\Users\rdtla\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\discord\channel.py", line 567, in create_webhook
avatar = utils._bytes_to_base64_data(avatar) # type: ignore
File "C:\Users\rdtla\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\discord\utils.py", line 482, in _bytes_to_base64_data
mime = _get_mime_type_for_image(data)
File "C:\Users\rdtla\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\discord\utils.py", line 468, in _get_mime_type_for_image
if data.startswith(b'\x89\x50\x4E\x47\x0D\x0A\x1A\x0A'):
TypeError: startswith first arg must be str or a tuple of str, not bytes
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\rdtla\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\discord\ext\commands\bot.py", line 1045, in invoke
await ctx.command.invoke(ctx)
File "C:\Users\rdtla\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\discord\ext\commands\core.py", line 951, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "C:\Users\rdtla\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\discord\ext\commands\core.py", line 188, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: startswith first arg must be str or a tuple of str, not bytes
Intents
guilds members bans emojis integrations webhooks invites voice_states presences guild_messages dm_messages guild_reactions dm_reactions guild_typing dm_typing
System Information
- Python v3.8.10-final
- Novus v0.0.3-final
- aiohttp v3.7.4.post0
- system info: Windows 10 10.0.19043
Checklist
- I have searched the open issues for duplicates.
- I have shown the entire traceback, if possible.
- I have removed my token from display, if visible.
Additional Context
No response
The avatar
parameter for .create_webhook()
takes a bytes object, not a string. So Asset.url
won't work.
You should retrieve the content of the Asset as a bytes object first, using await Asset.read()
. So in your case it would be await member.avatar.read()
.
The
avatar
parameter for.create_webhook()
takes a bytes object, not a string. SoAsset.url
won't work. You should retrieve the content of the Asset as a bytes object first, usingawait Asset.read()
. So in your case it would beawait member.avatar.read()
.
Thank you, this helped me. I think the TypeError is still something worth fixing though
What do you think should be fixed with this? This is working as intended - the avatar
parameter doesn't take a URL.
if data.startswith(b'\x89\x50\x4E\x47\x0D\x0A\x1A\x0A'):
TypeError: startswith first arg must be str or a tuple of str, not bytes
is this not a bug in the code?
No. You passed an incorrect set of data to the method (it takes a bytes-like object, not a URL) and it errored accordingly.