# 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.

```text
getattr  __name__  __class__  __builtins__  __bases__  __subclasses__
__build_class__  __getattribute__  __closure__  cell_contents  __base__  __mro__
```

```python
# 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.

```python
import random        # removed, does nothing
pick = random(["a", "b", "c"])   # use the built-in random(...) instead
```

## print does not exist

`print(...)` fails. To see a value, put it in the reply:

```python
set_content(f"Debug: {my_value}")
```

## Sending with .send()

Discord's own send methods are blocked. Use the helpers. They count toward [limits](https://ccbot.app/docs/concepts/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](https://ccbot.app/docs/getting-started/how-commands-run).

## 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:

```text
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 call
```

Without `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](https://ccbot.app/docs/concepts/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:

```python
if user is None or user.is_bot:
    return
```

## Still 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](https://ccbot.app/docs/getting-started/slushy).
