Concepts
Common mistakes
The mistakes that make a command do nothing or fail, and how to fix each one.
Your command does nothing, or shows an error? Check this list first.
Blocked words anywhere in the code#
Some words are blocked for safety. If one appears anywhere in your code, the whole script is turned off and nothing runs. No error shows.
This includes text inside quotes and comments.
getattr __name__ __class__ __builtins__ __bases__ __subclasses__
__build_class__ __getattribute__ __closure__ cell_contents __base__ __mro__# Breaks the whole command, even though it is only a message:
set_content("Use getattr for this")getattr and __name__ are the ones people write by accident.
import does nothing#
There is nothing to import. Every function in these docs is already there. An import line is removed.
import random # removed, does nothing
pick = random(["a", "b", "c"]) # use the built-in random(...) insteadprint does not exist#
print(...) fails. To see a value, put it in the reply:
set_content(f"Debug: {my_value}")Sending with .send()#
Discord's own send methods are blocked. Use the helpers. They count toward limits the right way.
| Do not write | Write |
|---|---|
channel.send("hi") | send_message(channel, "hi") |
member.send("hi") | send_dm(member, "hi") |
message.respond("hi") | send_message(channel, "hi", reply=message.id) |
member.add_role(role) | add_roles(member, role) |
member.remove_role(role) | remove_roles(member, role) |
Using response in the pre-hook#
response is the bot's reply. It only exists in the Post-hook, after the reply is sent.
set_content in the post-hook#
The reply is already sent when the post-hook runs. set_content there does nothing. Use send_message or edit_message instead.
end() did not stop the code#
end() only cancels the reply. The lines after it in the pre-hook still run. Use set_error("text") to stop right away. See How a command runs.
Calling view.wait() after set_view#
set_view(view) already waits for the buttons. Calling view.wait() again waits twice. Remove it.
Forgetting await#
Many functions get await added for you, like send_message, add_roles and update_member_var. Others need it written by hand:
fetch ask_ai render_template load_script sleep schedule
send_modal defer wait_for create_poll create_event
lock_channel unlock_channel set_slowmode list_members
view.update_view paginator.start every Mongo callWithout await, these do nothing. Writing await is always safe, so when in doubt, write it.
Clicks say "This interaction failed"#
Discord waits 3 seconds for an answer to a click. Answer first, then do the work:
- In a View button:
await defer(interaction, action="update") - In a Button Click event:
defer_response()
See Buttons and menus.
Reading the menu choice from component#
In a menu callback, component.values is not the user's choice. Use interaction.values[0].
An argument hides a variable#
An argument named user, channel or server replaces the built-in one. Name it target or member instead.
Saved numbers are text#
member_var and server_var give back text. "100" + 1 fails. Use int(member_var("coins", 0)).
Made-up names#
Only the functions in these docs exist. A guessed name like edit_role or get_user fails. Search the docs with Ctrl K to find the right one.
Message event replies to itself#
A MESSAGE event also runs for the bot's own messages. Start with:
if user is None or user.is_bot:
returnStill stuck?#
- Open Logs → Error Logs on the dashboard. It shows the real error.
- Ask Slushy: press Fix with Slushy on the error. See Using Slushy.