#Not allowed to use slash commands in Discord server

1 messages · Page 1 of 1 (latest)

young nebula
#

I'm trying to use slash commands for my bot in a Discord server, but it says "You are not authorized to use this command."

I can use them in DMs.

@runic verge

runic vergeBOT
#

That message is coming from OpenClaw’s own auth checks, not Discord’s slash-command permissions.

DMs and guild channels are authorized separately:

  • In DMs, you’re allowed via channels.discord.dmPolicy + channels.discord.allowFrom (or pairing).
  • In a server, native slash commands use the same guild allowlist rules as normal messages. If the guild/channel isn’t allowlisted under channels.discord.guilds, you’ll get “not authorized” (even though the command shows up in the UI).

Fix (recommended: allowlist the guild + channel)

In openclaw.json, add your server + channel:

{
  channels: {
    discord: {
      groupPolicy: "allowlist",
      guilds: {
#
        "YOUR_GUILD_ID": {
          // optional but common (locks it to you / a role)
          users: ["YOUR_USER_ID"], // or roles: ["ROLE_ID"]

          channels: {
            "YOUR_CHANNEL_ID": { allow: true }
          }
        }
      }
    }
  }
}

Notes:

  • If you’re running the command inside a thread, the “channel” is the thread id (so allowlist that id, or omit the channels block to allow all channels in that guild).
wary mango
#

what about when groupPolicy: open ? Shouldn't that mean anyone can use slash commands? Is this a bug?

runic vergeBOT
#

groupPolicy: "open" does mean “don’t require a guild/channel allowlist” — so in principle, yes: anyone in any server/channel should be able to run the non-owner slash commands.

When people hit “You are not authorized…” anyway, it’s almost always one of these:

1) You don’t actually have a channels.discord block, so Discord falls back to allowlist

This one is super common. From the Discord docs:

If you only set DISCORD_BOT_TOKEN and do not create a channels.discord block, runtime fallback is groupPolicy="allowlist" … even if channels.defaults.groupPolicy is open.

So if you only set the env var, you’ll still be blocked in guilds until you explicitly configure Discord.

Fix: add a minimal block:

{
  channels: {
#
    discord: {
      enabled: true,
      groupPolicy: "open",
      // token can stay in DISCORD_BOT_TOKEN (OpenClaw will pick it up)
    },
  },
}

Then restart the gateway.

You can confirm what’s actually active with:

openclaw config get channels.discord.groupPolicy
#
openclaw config validate

2) You’re testing an owner-only command

Some commands are still restricted even in open servers (e.g. /config, /debug, allowlist writes, elevated/exec-related flows). Those will return “not authorized” for non-owners by design.

3) You do have guild/channel restrictions configured somewhere

If you set channels.discord.guilds.<id>.channels and the channel (or thread channel id) isn’t included, you’ll be denied in that location.

If you paste your channels.discord config (redact token) + which slash command you’re running, I can tell you exactly which of the above you’re hitting.

wary mango
#

"discord": {
"enabled": true,
"token": "foobar",
"groupPolicy": "open",
"streaming": "partial",
"guilds": {
"mine": {
"requireMention": false
}
}
},

#

trying /status

runic vergeBOT
#

That config explains it.

Even though you set:

groupPolicy: "open"

you also set a non-empty channels.discord.guilds map:

guilds: {
  "mine": { requireMention: false }
}

In practice, once you configure guilds, OpenClaw treats that as “these are the guilds I’m willing to operate in” — so if the incoming guild doesn’t match one of those keys, native slash commands (and messages) will be rejected as “not authorized”.

#

So right now your bot is only “open” within a guild that matches "mine" — and "mine" is almost certainly not your real guild id/slug.

Fix

Use the actual guild ID as the key (recommended):

guilds: {
  "123456789012345678": { requireMention: false }
}

(Or use the guild slug exactly as OpenClaw expects, but IDs are way less error-prone.)

After editing, run:

#
openclaw config validate

and restart the gateway.

Quick test

If you remove the guilds block entirely, slash commands should work everywhere under groupPolicy: "open" (mention-gating only affects normal messages, not slash commands).

#

/status is a “normal” command (not owner-only), so if it’s returning not authorized in a guild, it’s almost always because the guild isn’t considered allowed.

With your current config, the likely cause is still the guilds: { "mine": ... } entry: "mine" doesn’t match your actual server ID/slug, so OpenClaw treats the command as coming from a non-allowed guild.

Do this:

  1. In Discord enable Developer Mode
  2. Right-click your server → Copy Server ID
  3. Use that as the key:
channels: {
  discord: {
    groupPolicy: "open",
    guilds: {
      "YOUR_REAL_GUILD_ID": { requireMention: false }
#
    }
  }
}

Then openclaw config validate + restart the gateway.

(If you temporarily delete the whole guilds block, /status should work everywhere with groupPolicy:"open"—that’s a quick sanity check.)

wary mango
#

ugh. I put those placeholder tokens. They are surely working because I do get responses from the bot in the discord guild. But I'll try removing that block. I only added it because I explicitly wanted responses from every message, not having to mention

runic vergeBOT
#

Yep — disabling mention-gating is exactly what requireMention: false is for.

But that’s separate from “who is allowed to run slash commands”.

Even if you let the bot respond to every message in the guild, OpenClaw can still treat slash commands/directives (like /status) as an operator/control-plane feature and require an authorized sender for commands.

Two sane ways to get what you want

Option A (recommended for most setups): keep guilds allowlisted, but no mentions needed

This gives you “respond to every message” in your server, without opening the bot to every server it might join:

channels: {
  discord: {
    groupPolicy: "allowlist",
    guilds: {
#
      "YOUR_GUILD_ID": {
        requireMention: false
        // no users/roles filter => everyone in that guild can chat + use /status
      }
    }
  }
}

Option B: keep groupPolicy: "open" (respond everywhere), but explicitly allow you to run commands

Add a command allowlist:

commands: {
  allowFrom: {
#
    discord: ["289783215974121472"] // your Discord user id
  }
}

(If you set discord: ["*"], then literally anyone can run slash commands — usually not what you want.)

After either change: openclaw config validate + restart.

If you tell me which of those behaviors you want (“everyone can /status” vs “only me can /status”), I’ll point you at the least risky config for it.

wary mango
#

dang son, talking yourself in circles! So I implemented option A, AND B just to be more secure. And guess what. STILL getting the not authorized message.

runic vergeBOT
#

If you’ve truly got (A) groupPolicy: "allowlist" + your real guild id configured and (B) commands.allowFrom.discord includes your user id, then OpenClaw would not be the thing blocking /status.

At that point, the most likely culprit is Discord is blocking the interaction before it ever reaches the bot.

Quick ways to tell

  1. When you type /status, does the autocomplete entry show your bot’s icon/name next to the command?

    • If it’s some other app’s /status, you’ll chase the wrong thing forever.
  2. Check your gateway logs while you run /status in the server:

    • If the gateway logs nothing about an interaction/command, Discord prevented it.
    • If the gateway logs it and then says “not authorized”, then it’s OpenClaw auth.

Discord-side things that cause exactly this

  • Channel/server permission “Use Application Commands” is denied (either for you, or for the bot) in that channel/thread.
  • Server Settings → Integrations → your app → command permissions: /status is disabled for your role / @everyone.

Can you try /status in a different channel in the same server? If it works elsewhere, it’s almost certainly a channel permission override (“Use Application Commands”).

#

If you paste your commands.allowFrom block (not the Discord token) and tell me whether the gateway logs an interaction when you run /status, I can tell you which side is blocking it.

wary mango
#

nothing shows up in openclaw logs --follow for slash commands. Use Application Commands is enabled for both the bot and me. when I type /status the name of the bot shows up next to it. if I mention that exact bot or just talk, that bot can talk and respond to me.

"commands": {
"native": "auto",
"nativeSkills": "auto",
"restart": true,
"ownerDisplay": "raw",
"allowFrom": {
"discord": [
"289783215974121472"
]
}
},

#

btw I'm using 2026.3.2

runic vergeBOT
#

Ok, this is the key detail: on Discord native slash commands have an extra “command gate” before OpenClaw even looks at commands.allowFrom.

That gate (for guild interactions) only considers either:

  1. “Owner” allowlist via channels.discord.allowFrom (or legacy channels.discord.dm.allowFrom), and/or
  2. Member allowlists via channels.discord.guilds.<id>.users / .roles (if you configured those)

If neither of those is configured, commands.useAccessGroups=true will make all guild slash commands return “not authorized” — even if the bot is happily chatting in the guild and even if commands.allowFrom is set.

Fix (minimal, keeps your “respond to every message” setup)

Add yourself to the Discord owner allowlist:

channels: {
  discord: {
    // ...
#
    allowFrom: ["user:289783215974121472"], // or just "289783215974121472"
  }
}

Keep your guilds: { "...": { requireMention: false } } as-is.

Then restart the gateway and retry /status.

Why your current commands.allowFrom didn’t help

commands.allowFrom is checked later for “is this sender allowed to use directives/commands”, but the Discord slash-command handler first enforces the access-group gate described above. So you were allowlisting yourself in the second lock while the first lock was still closed.

If adding channels.discord.allowFrom fixes it, you can probably remove the commands.allowFrom block unless you specifically want command auth to differ from normal message auth.

If it still fails after that, paste your channels.discord block (minus token) and tell me whether you’re running in a normal channel vs a thread.

#

Cool — 2026.3.2 is recent enough; nothing “ancient version” going on here.

Given what you’ve shown, the missing piece is still this:

  • You’re using DM pairing (so channels.discord.allowFrom is probably empty)
  • For guild slash commands, the first authorization gate looks at channels.discord.allowFrom (owner allowlist) and/or guild member allowlists (guilds.*.users/roles) — it does not treat pairing approvals as “command-authorized” for guild slash commands.

So add yourself explicitly as the Discord owner allowlist and restart:

channels: {
  discord: {
    dmPolicy: "pairing",
    allowFrom: ["user:289783215974121472"], // <-- add this
    groupPolicy: "allowlist",               // your Option A
    guilds: {