#exec Approval button doesn't show on DC AND couldn't work on tele

1 messages · Page 1 of 1 (latest)

glad gale
#

I'm been work on this bug for 3 days and couldn't fix it. My environment is windows +ubuntu(not WSL)
I set my DC bot right, checked every "turn on" they need
This is my config:

   "approvals": {
    "exec": {
      "enabled": true,
      "mode": "targets",
      "agentFilter": [
        "main",
        "go-master"
      ],
      "targets": [
        {
          "channel": "telegram",
          "to": "5613181787"
        },
        {
          "channel": "discord",
          "to": "721291307166859300"
        }
      ]
    }
  },
  "channels": {
    "telegram": {
      "capabilities": {
        "inlineButtons": "dm"
      },
      "enabled": true,
      "dmPolicy": "pairing",
      "botToken": "__OPENCLAW_REDACTED__",
      "groupPolicy": "open",
      "streamMode": "partial"
    },
    "discord": {
      "capabilities": [
        "markdown",
        "mentions",
        "attachments",
        "actions"
      ],
      "enabled": true,
      "token": "__OPENCLAW_REDACTED__",
      "groupPolicy": "open",
      "actions": {
        "reactions": true,
        "stickers": true,
        "emojiUploads": true,
        "stickerUploads": true,
        "polls": true,
        "permissions": true,
        "messages": true,
        "threads": true,
        "pins": true,
        "search": true,
        "memberInfo": true,
        "roleInfo": true,
        "roles": true,
        "channelInfo": true,
        "voiceStatus": true,
        "events": true,
        "moderation": true,
        "channels": true,
        "presence": true
      },
      "dmPolicy": "open",
      "allowFrom": [
        "*"
      ],
      "dm": {
        "enabled": true
      }
    }
  }
hushed pulsarBOT
#

To help others find answers, you can mark your question as solved via Right click solution message -> Apps -> âś… Mark Solution

glad gale
#

And these are the errors when I use openclaw log --follow

15:40:47 error [tools] exec failed: ls: cannot open directory '/root': Permission denied

Command exited with code 2
15:40:47 error [tools] exec failed: ls: cannot open directory '/root': Permission denied

Command exited with code 2
15:41:12 debug agent/embedded ....
15:41:22 info Writing local approvals.
15:41:22 info Pattern not found.
..{"subsystem":"agent/embedded"} embedded run tool start: runId=4287fc8c-1879-4833-a14d-e8d92f4399ee tool=exec toolCallId=exec_1771256488294_7
15:41:28 error [tools] exec failed: cat: /etc/shadow: Permission denied

Command exited with code 1
15:41:28 error [tools] exec failed: cat: /etc/shadow: Permission denied

Command exited with code 1
unkempt tinselBOT
#

You’re mixing two different exec-approval features, and that’s why you’re not seeing “buttons”.

1) approvals.exec (your config) = forwarding + /approve (no buttons)

This block:

approvals: { exec: { ... targets: [...] } }

forwards approval prompts as plain text and you approve by typing:

/approve <id> allow-once
/approve <id> allow-always
/approve <id> deny
#

Docs: https://docs.openclaw.ai/tools/exec-approvals

Your Discord target is very likely wrong

For Discord, raw numeric IDs are treated as channels. If 721291307166859300 is your user id (DM), you must prefix it:

approvals: {
  exec: {
    enabled: true,
    mode: "targets",
    targets: [
      { channel: "discord", to: "user:721291307166859300" }, // DM a user
      // or { channel: "discord", to: "channel:123..." }     // post in a channel
    ]
  }
}
#

This is explicitly documented under openclaw message target formats: https://docs.openclaw.ai/cli/message (Discord: channel:<id> or user:<id>; raw numeric → channel)

2) Discord “approval buttons” = channels.discord.execApprovals

If what you want is the Approve/Deny buttons in Discord, that is configured here (not in approvals.exec.targets):

channels: {
  discord: {
    execApprovals: {
      enabled: true,
      approvers: ["721291307166859300"],  // your Discord user id(s)
      target: "dm"                        // "dm" | "channel" | "both"
    }
  }
}
#

Docs: https://docs.openclaw.ai/channels/discord (section “Exec approvals in Discord”)

Notes:

  • Default is DM. If you expect buttons in the channel, set target: "channel" or "both".
  • “channel/both” posts to the originating Discord channel (it’s not controlled by approvals.exec.targets.to).

3) About “telegram channel id 1472985536083005594”

That number looks like a Discord snowflake, not a Telegram chat id.
Telegram chat ids are usually:

  • a positive integer for a user DM, or
  • negative (often starts with -100...) for groups/channels.

Also: Telegram bots cannot DM a user unless the user has started the bot (sent /start at least once).

4) Quick sanity check (most common gotcha)

Approval prompts only exist when the exec is actually running with host approvals (e.g. host=gateway/host=node with ask=always or allowlist miss). If your exec is running in sandbox / not triggering approvals, nothing will be forwarded and no buttons will appear.

#

If you paste:

  1. openclaw --version
  2. whether you want approvals to show in Discord DM or channel
  3. one log snippet around an attempted exec approval (search for exec approval)

…I can tell you exactly which path you’re currently hitting and what to change.

#

Those log lines are just normal Linux permissions, not an “OpenClaw exec is broken” signal:

  • ls /root: Permission denied → your Gateway process is not running as root, so it can’t read /root.
  • cat /etc/shadow: Permission denied → even more strict: only root can read it.

Important: Exec approvals do not grant extra OS privileges. They only decide whether a command is allowed to run on the host (gateway/node). If the OS user running OpenClaw can’t access a path, the command will still fail.

Why the “approval button” isn’t showing in Discord

Discord’s button-based exec approvals only show in DMs, not in guild channels/threads.

Docs: https://docs.openclaw.ai/channels/discord#exec-approvals-in-discord
Exec approvals overview: https://docs.openclaw.ai/tools/exec-approvals

To get the DM buttons working you need (and then restart gateway after config changes):

{
#
  channels: {
    discord: {
      execApprovals: {
        enabled: true,
        approvers: ["<YOUR_DISCORD_USER_ID>"]
      }
    }
  }
}

Then DM the bot, trigger an exec that requires approval, and the buttons should appear in that DM.

About “couldn’t work on tele channel id:1472985536083005594”

That number looks like a Discord snowflake, not a Telegram chat id.

For Telegram:

#
  • channels.telegram.allowFrom wants the human sender’s Telegram user id (or @username), not a channel id.
  • Telegram group chat ids are usually negative (often -100...).

Docs/FAQ section: https://docs.openclaw.ai/help/faq#telegram-what-goes-in-allowfrom
Telegram channel docs: https://docs.openclaw.ai/channels/telegram

What to do next (so we can pinpoint your setup)

Paste outputs (redact tokens):

  1. openclaw --version
  2. openclaw status --all
  3. Tell me: were you expecting approval buttons in the server thread or in DMs?

And if your actual goal is “run root-only commands”: the safe pattern is usually to NOT run the Gateway as root, but instead configure very specific sudo -n <command> rules via sudoers for only the binaries you truly need.

glad gale
#

Thanks for your reply

Version: 2026.2.15
OS : linux 5.15.146.1-microsoft-standard-WSL2 (x64)
Node : 22.22.0
Config :~/.openclaw/openclaw.json
Dashboard :http://127.0.0.1:18789/
Tailscale: off
Channel: stable (default)
Update : pnpm · npm latest 2026.2.15
Gateway : local · ws://127.0.0.1:18789 (local loopback) · reachable 18ms · auth password
Security : Run: openclaw security audit --deep
Gateway self:Connor (172.26.5.203) app unknown linux 5.15.146.1-microsoft-standard-WSL2
Gateway service:systemd installed · enabled · running (pid 899)
Node service : systemd not installed
Agents : 4 total · 1 bootstrapping · 1 active · 33 sessions

(Telegram and DC account status is OK)

#

Diagnosis (read-only)

Gateway connection details:
Gateway target: ws://127.0.0.1:18789
Source: local loopback
Config: /home/connerxwolf/.openclaw/openclaw.json
Bind: tailnet

âś“ Config: /home/connerxwolf/.openclaw/openclaw.json
âś“ Restart sentinel: none
! Port 18789
Port 18789 is already in use.

  • pid 899 connerxwolf: openclaw-gateway (127.0.0.1:18789)
  • Gateway already running locally. Stop it (openclaw gateway stop) or use a different port.
    ! Tailscale: off · unknown
    error: Error: spawn tailscale ENOENT
    ✓ Skills: 9 eligible · 0 missing · /home/connerxwolf/.openclaw/workspace
    âś“ Channel issues (none)

Pasteable debug report. Auth tokens redacted.
Troubleshooting: https://docs.openclaw.ai/troubleshooting

#

I expect the approval buttons in the server thread

unkempt tinselBOT
#

Yep, that status dump looks healthy (2026.2.15 on WSL2 is fine).

1) The Permission denied exec errors are expected

/root and /etc/shadow are root-only on Linux. Even if exec approvals are working perfectly, OpenClaw still runs commands as the OS user that the gateway service runs under, so it can’t read those paths.

If your goal is “run root-only stuff”, you’ll need a deliberate sudo setup (very tight sudoers rules), not approvals.


2) Why the Discord approval buttons don’t show

Discord’s button-based exec approvals only appear in Discord DMs, and only to users listed as approvers.

So if you’re expecting the buttons inside this server thread: they won’t show there.

Checklist:

  • In config:
#
  {
    channels: {
      discord: {
        execApprovals: {
          enabled: true,
          approvers: ["<your_discord_user_id>"]
        }
      }
    }
  }
  • Restart gateway after changing config: openclaw gateway restart
  • Make sure Discord allows the bot to DM you (common gotcha):
    • Server → Privacy Settings → Allow direct messages from server members (ON), or equivalent user privacy setting.

Docs: https://docs.openclaw.ai/channels/discord#exec-approvals-in-discord

#

3) If you want approvals in the thread (or Telegram): use “approval forwarding”

This is separate from the Discord DM buttons. It forwards the approval prompt to chat and you approve with /approve:

{
  approvals: {
    exec: {
      enabled: true,
      mode: "session",          // send to the same session that triggered it
      sessionFilter: ["discord"] // optional but helps avoid noise
    }
  }
}
#

Then you’ll see an approval id in chat and can run:

  • /approve <id> allow-once
  • /approve <id> allow-always
  • /approve <id> deny

Docs: https://docs.openclaw.ai/tools/exec-approvals#approval-forwarding-to-chat-channels


4) Telegram ID confusion

1472985536083005594 looks like a Discord channel/thread id, not Telegram.

For Telegram:

  • channels.telegram.allowFrom should be your Telegram user id (numeric) or @username.
  • To discover it: DM the bot once, then check openclaw logs --follow and look for from.id.

Docs: https://docs.openclaw.ai/help/faq#telegram-what-goes-in-allowfrom

#

If you paste just these config sections (redact tokens), I can tell you exactly what’s off:

  • channels.discord.execApprovals
  • approvals.exec
  • channels.telegram.allowFrom
#

That openclaw doctor output is basically saying two things (neither is related to Discord approval buttons directly):

  1. Port already in use
    You already have the gateway running via systemd:
  • pid 899 connerxwolf: openclaw-gateway (127.0.0.1:18789)

So if you manually ran openclaw gateway in a shell, it will complain. Use one of these instead:

  • openclaw gateway restart (usually what you want)
  • openclaw gateway stop / openclaw gateway start
  1. Tailscale not installed in WSL (spawn tailscale ENOENT)
    Your config says Bind: tailnet, but there is no tailscale binary inside WSL, and Tailscale is off. If you’re not actually using Tailscale, switch bind away from tailnet:

Docs: https://docs.openclaw.ai/help/faq#i-set-gatewaybind-tailnet-but-it-cant-bind-nothing-listens


#

Getting the Discord exec approval buttons to show (the real fix)

Discord “approval buttons” only exist as DMs to approvers, and only if this is configured:

{
  channels: {
    discord: {
      execApprovals: {
        enabled: true,
        approvers: ["<YOUR_DISCORD_USER_ID>"]
      }
    }
  }
}

Also make sure your Discord privacy allows DMs from the bot (otherwise the DM with buttons can’t arrive).

#

Docs: https://docs.openclaw.ai/channels/discord#exec-approvals-in-discord

Quick check: paste these (redact tokens)

Run and paste outputs:

openclaw config get channels.discord.execApprovals
openclaw approvals get --gateway

That will tell us immediately whether:

  • Discord execApprovals is enabled + approver list is correct, and
  • your gateway exec approvals are actually set to a mode that would prompt.

One extra gotcha from your earlier logs: “Pattern not found.”

If you tried allowlisting stuff like ls or cat by basename, it won’t work. Allowlists want full paths/globs (e.g. /usr/bin/ls, not ls). This commonly leads to “why didn’t I get a prompt / why is it denying”.

#

If you paste openclaw approvals get --gateway we can see exactly what patterns you have right now.

#

Discord cannot show the exec-approval buttons in a server thread with the current OpenClaw implementation.

  • The button UI is DM-only (“Exec approvals in Discord” = DM buttons).
  • If you want to approve from the thread, you must use approval forwarding (it posts a message containing an approval id), then you approve via /approve in the thread.

Docs:

What to configure (thread approvals)

Add this to your config:

{
  approvals: {
    exec: {
#
      enabled: true,
      mode: "session",          // sends prompt back into the same session/thread
      sessionFilter: ["discord"] // optional
    }
  }
}

Then restart:

openclaw gateway restart

How it will look in the thread

When an exec needs approval, the bot posts something like “approval requested … id=…”.
Then run in the thread:

#
  • /approve <id> allow-once
  • /approve <id> allow-always
  • /approve <id> deny

If /approve doesn’t appear as a Discord command

Run this and paste output:

openclaw config get channels.discord.commands.native

(If native commands are disabled, Discord won’t offer slash commands reliably.)

If you paste your approvals.exec section (and whether /approve shows up at all), I’ll tell you the exact next tweak.

glad gale
#

i think i do it right but it can't work:

"bindings": [
{
"agentId": "isolated",
"match": {
"channel": "discord",
"peer": {
"kind": "channel",
"id": "1472196943324123314"
}
}
}
],
"messages": {
"ackReactionScope": "group-mentions"
},
"commands": {
"native": "auto",
"nativeSkills": "auto",
"config": true,
"restart": true
},
"approvals": {
"exec": {
"enabled": true,
"mode": "session",
"sessionFilter": ["discord", "telegram"]
}
},
"channels": {
"telegram": {
"capabilities": {
"inlineButtons": "dm"
},
"enabled": true,
"dmPolicy": "pairing",
"botToken": "OPENCLAW_REDACTED",
"groupPolicy": "open",
"streamMode": "partial",
"allowFrom": [
"5613181787"
],
"execApprovals": {
"enabled": true,
"approvers": [
"5613181787"
]
}
},
"discord": {
"capabilities": [
"markdown",
"mentions",
"attachments",
"actions"
],
"enabled": true,
"token": "OPENCLAW_REDACTED",
"groupPolicy": "open",
"actions": {
"reactions": true,
"stickers": true,
"emojiUploads": true,
"stickerUploads": true,
"polls": true,
"permissions": true,
"messages": true,
"threads": true,
"pins": true,
"search": true,
"memberInfo": true,
"roleInfo": true,
"roles": true,
"channelInfo": true,
"voiceStatus": true,
"events": true,
"moderation": true,
"channels": true,
"presence": true
},
"dmPolicy": "open",
"allowFrom": [
"*"
],
"dm": {
"enabled": true
},
"execApprovals": {
"enabled": true,
"approvers": [
"721291307166859288"
]
}
}
},

unkempt tinselBOT
#

Two separate “exec approval” features are getting mixed together here:

A) Discord buttons (channels.discord.execApprovals) are DM-only

This part of your config is fine, but it will never show buttons inside a server thread:

channels: {
  discord: {
    execApprovals: { enabled: true, approvers: ["721291307166859288"] }
  }
}

Buttons only appear in Discord DMs to the approver(s). They won’t render in a guild channel/thread.

Docs: https://docs.openclaw.ai/channels/discord#exec-approvals-in-discord

#

B) Thread approvals use forwarding + /approve (no buttons)

This is your top-level:

approvals: {
  exec: { enabled: true, mode: "session", sessionFilter: ["discord", "telegram"] }
}

That does not create buttons. It forwards an approval request message containing an approval id, and you approve with:

  • /approve <id> allow-once
  • /approve <id> allow-always
  • /approve <id> deny

Docs: https://docs.openclaw.ai/tools/exec-approvals#approval-forwarding-to-chat-channels

#

Why you’re seeing “it can’t work” (most common cause)

In OpenClaw, approvals only trigger when you run exec on the host:

  • exec host=gateway or exec host=node

If you run exec in the default mode (host=sandbox), and sandboxing is off (common on Linux/WSL), it runs directly on the gateway host without approvals, so there is nothing to forward.

Docs (important note): https://docs.openclaw.ai/tools/exec#parameters


Quick “make it work” test (in the Discord thread)

  1. In the thread, run:
#
/exec host=gateway security=allowlist ask=always
  1. Then ask the bot to run something not allowlisted, e.g.:
run: /usr/bin/uname -a

You should then see a message in the thread with an approval id, and you approve with:

/approve <id> allow-once

If you don’t see any approval-id message, paste these two outputs (redact tokens):

#
openclaw approvals get --gateway
openclaw config get tools.exec

One config issue: Telegram execApprovals is ignored

This block does nothing (Telegram channel has no execApprovals setting):

channels.telegram.execApprovals

Telegram approvals (if you want them) should be handled via the same top-level approvals.exec forwarding config.

If you tell me whether /exec and /approve show up as slash commands in that thread, I can narrow the next step immediately.

glad gale
#

i swift the exec host to gateway but I still couldn't see the button in the discord DM
And after I use /approve
THE log shows:
01:17:13 error discord exec approvals: failed to notify user 721291307166859300: Error: Invalid Recipient(s)
01:17:13 error discord exec approvals: failed to notify user 721291307166859300: Error: Invalid Recipient(s)

unkempt tinselBOT
#

That error is coming from Discord itself: the bot tried to open a DM to that approver user ID and Discord rejected it.

Two big clues:

1) Your log user ID doesn’t match your config

Log:

  • failed to notify user 721291307166859300

Your config snippet earlier:

  • approvers: ["721291307166859288"]

Those are different IDs. So either:

  • the running gateway is using a different config than the one you pasted, or
  • the approver ID in your real config has a typo.

Verify what the running gateway is actually using:

#
openclaw config get channels.discord.execApprovals
openclaw gateway restart

2) “Invalid Recipient(s)” usually means one of:

  • the ID is not a real user ID (common: copied channel/thread/message ID by accident), or
  • Discord won’t allow the bot to DM you due to privacy/block settings.

Fix checklist (Discord side)

  1. In Discord, enable Developer Mode
  2. In the server member list, right-click your own user → Copy User ID
    Put that exact value into:
    channels.discord.execApprovals.approvers: ["<your user id>"]
    
  3. Make sure you allow DMs:
#
  • Server → Privacy Settings → Allow direct messages from server members = ON
    (and make sure you didn’t block the bot)
  1. DM the bot first (send “hi”). This often helps because it creates the DM channel.

If your goal is approvals inside the thread (not DM buttons)

DM buttons are a separate feature. For thread approvals, use forwarding + /approve (no buttons). Your approvals.exec config is the right direction for that.

If you paste the output of openclaw config get channels.discord.execApprovals (redact token), I can tell you immediately why it’s trying to DM ...300.

glad gale
#

ok, now i put my dc id right
my goal is use the approval buttom
but it still showed the same error
my discord id is 721291307166859288
but it showed 01:33:07 error discord exec approvals: failed to notify user 721291307166859300: Error: Invalid Recipient(s)
My config is:
"discord": {
"capabilities": [
"markdown",
"mentions",
"attachments",
"actions"
],
"enabled": true,
"token": "OPENCLAW_REDACTED",
"groupPolicy": "open",
"actions": {
"reactions": true,
"stickers": true,
"emojiUploads": true,
"stickerUploads": true,
"polls": true,
"permissions": true,
"messages": true,
"threads": true,
"pins": true,
"search": true,
"memberInfo": true,
"roleInfo": true,
"roles": true,
"channelInfo": true,
"voiceStatus": true,
"events": true,
"moderation": true,
"channels": true,
"presence": true
},
"dmPolicy": "open",
"allowFrom": [
"*"
],
"dm": {
"enabled": true
},
"execApprovals": {
"enabled": true,
"approvers": [
721291307166859288
]
}
}
},

unkempt tinselBOT
#

That ...288 → ...300 change is a classic 64‑bit Discord snowflake precision bug.

What’s happening

You put the approver as a number:

"approvers": [
  721291307166859288
]

But Discord IDs are 64-bit integers, and JS Number can’t represent them exactly (anything > 2^53 loses precision). So it gets rounded to:

721291307166859300

…and Discord replies Invalid Recipient(s) because that user ID doesn’t exist.

#

Fix

Make it a string (quoted):

"execApprovals": {
  "enabled": true,
  "approvers": ["721291307166859288"]
}

Then restart the gateway:

openclaw gateway restart

If it still can’t DM after that

#

Then it’s Discord privacy settings (DMs disabled / bot blocked). Quick checks:

  • Make sure you can DM the bot (send “hi” to it once).
  • Discord server privacy: Allow direct messages from server members = ON (for that server), and you haven’t blocked the bot.

But first: change approvers to a quoted string — your log proves it’s currently being rounded.

glad gale
#

now i can approve in DM use the button
but if only i give the command in the DM
if i give the command in the server
i can still receive the approval button
but it shows nothing after i tap the allow button :
01:52:08 debug agent/embedded {"subsystem":"agent/embedded"} embedded run prompt start: runId=30ea4abe-9881-41ee-a813-29e11d6e96b4 sessionId=41e31808-c369-4664-8c79-cd82802b2d68
01:52:08 debug agent/embedded {"subsystem":"agent/embedded"} embedded run agent start: runId=30ea4abe-9881-41ee-a813-29e11d6e96b4
01:52:11 info exec {"subsystem":"exec"} elevated command ls -f
01:52:11 debug agent/embedded {"subsystem":"agent/embedded"} embedded run tool start: runId=30ea4abe-9881-41ee-a813-29e11d6e96b4 tool=exec toolCallId=exec_1771293131741_2
......
01:52:15 debug diagnostic {"subsystem":"diagnostic"} lane task done: lane=main durationMs=7756 active=0 queued=0
01:52:15 debug diagnostic {"subsystem":"diagnostic"} lane task done: lane=session:agent:main:discord:channel:1471771522682327132 durationMs=7758 active=0 queued=0
01:52:17 info gateway/ws {"subsystem":"gateway/ws"} ⇄ res ✓ exec.approval.request 6191ms conn=51e095e8…9c16 id=22b85695…85ac
01:52:18 debug diagnostic {"subsystem":"diagnostic"} lane enqueue: lane=session:agent:main:main queueSize=1
01:52:18 debug diagnostic {"subsystem":"diagnostic"} lane dequeue: lane=session:agent:main:main waitMs=1 queueSize=0
01:52:18 debug diagnostic {"subsystem":"diagnostic"} lane enqueue: lane=main queueSize=1
01:52:18 debug diagnostic {"subsystem":"diagnostic"} lane dequeue: lane=main waitMs=1 queueSize=0
01:52:18 debug agent/embedded {"subsystem":"agent/embedded"} embedded run start: runId=789ebde4-01b6-4e7f-8cb0-84ba4aaf121a sessionId=ab7393df-e40a-4836-a0e4-213b994c0ce1 provider=google model=gemini-3-flash-preview thinking=low messageChannel=heartbeat
01:52:18 debug diagnostic {"subsystem":"diagnostic"} run registered: sessionId=ab7393df-e40a-4836-a0e4-213b994c0ce1 totalActive=1

unkempt tinselBOT
#

If the command originates in the server thread, the DM button is only the approval UI — the output/result is sent back to the server thread session, not to the DM.

So the first question is: after you tap Allow once in DM, do you see anything in the server thread (sometimes a normal reply, sometimes an Exec finished/denied-style system message)? If you were only watching the DM, it can look like “nothing happened”.

That said, your pasted log snippet doesn’t show an approval resolve, only the request:

  • âś… exec.approval.request ... (approval was created)
  • (missing) exec.approval.resolve ... (you clicked Allow)
  • (missing) Exec finished / exec exitCode=... / Discord send output

1) Confirm the click is being received

Run openclaw logs --follow, reproduce once, and after you click Allow in DM, look for a line containing exec.approval.resolve (or anything like “resolved allow-once”).

If there is no resolve log, then Discord is not delivering the button interaction to the bot (rare, but possible if the interaction fails on Discord side).

2) Most common real issue: bot can’t post back into that thread

When the command starts in a forum/thread, the bot needs Discord perms to send there (especially Send Messages in Threads).

#

Run:

openclaw channels status --probe

and paste the Discord part. If the bot can’t post into that thread, you’ll usually see “Missing Access / Missing Permissions” in either the probe or the gateway logs right after approval.

3) Quick sanity test

In the server thread, ask it something that doesn’t involve exec, like:

  • “say hello”

If the bot can’t reply normally in that thread, it also won’t be able to post the exec result there.


If you paste ~20–40 log lines right after clicking Allow (the section that should contain exec.approval.resolve and any Discord send error), I can tell you which of the two buckets you’re in immediately.

glad gale
#

Gateway reachable.

  • Telegram default: enabled, not configured, stopped, mode:polling, token:none, error:not configured
  • Discord default: enabled, configured, running, in:3h ago, out:10m ago, bot:@Shrimp, token:config, intents:content=limited, works, audit ok
#

i abandon telegram

unkempt tinselBOT
#

You’ve got two different “exec approval UX” paths, and your config is currently only enabling the chat-forwarded one (which usually does not show buttons on Discord).

1) Why the Discord approval buttons don’t show

Your snippet configures forwarding:

approvals: { exec: { mode:"targets", targets:[...] } }

That feature is documented under Exec approvals → “Approval forwarding to chat channels” and is approved via commands like:

  • /approve <id> allow-once
  • /approve <id> allow-always
  • /approve <id> deny

Docs: https://docs.openclaw.ai/tools/exec-approvals

#

If you want button-based approvals in Discord DMs, that’s a separate Discord-specific config:

channels: {
  discord: {
    execApprovals: {
      enabled: true,
      approvers: ["721291307166859300"], // your Discord USER id
      agentFilter: ["main", "go-master"],
    },
  },
}

Docs: https://docs.openclaw.ai/channels/discord (see “Exec approvals in Discord”)

Also: Discord approval buttons are DM-only, not in guild channels.

#

2) Your Discord “targets.to” value is probably wrong format for a DM

Discord delivery targets for DMs should be like:

  • user:<id> (recommended)
  • <@id>

So change this:

{ channel:"discord", to:"721291307166859300" }

to:

{ channel:"discord", to:"user:721291307166859300" }
#

(Otherwise it can be treated as ambiguous and get rejected.)

3) Telegram says “enabled, not configured, token:none” ⇒ the Gateway isn’t reading your Telegram token

Given your status output:

  • Telegram: enabled, not configured, stopped, token:none

…but your pasted config clearly includes channels.telegram.botToken, the most common cause is:

The gateway service is running with a different config/profile than the file you edited.

Run:

openclaw gateway status
#

and check whether it shows Config (cli) vs Config (service) pointing to different places. If they differ, fix it with:

openclaw gateway install --force
openclaw gateway restart

FAQ entry: https://docs.openclaw.ai/help/faq#why-does-openclaw-gateway-status-show-config-cli-and-config-service-different

4) If the Telegram target is a group/channel, your inlineButtons scope blocks it

You currently have:

channels.telegram.capabilities.inlineButtons: "dm"

If you’re trying to send approvals to a Telegram group/channel chat id, set:

#
  • "group" or "all" (or use "allowlist" properly)

Docs: https://docs.openclaw.ai/channels/telegram (see “Inline buttons”)


If you paste (redacting tokens) the output of:

  1. openclaw --version
  2. openclaw gateway status (the lines showing Config (cli)/(service))
    …I can tell you exactly which of the above is the blocker in your setup.
#

Got it — if you’re abandoning Telegram, then you basically have two Discord options, and only one of them has buttons:

Option A (buttons): Discord DM exec approvals

Buttons only exist for Discord DMs, via:

channels: {
  discord: {
    execApprovals: {
      enabled: true,
      approvers: ["<your_discord_user_id>"],
      agentFilter: ["main", "go-master"],
    },
  },
}
#

Docs: https://docs.openclaw.ai/channels/discord#exec-approvals-in-discord

Also make sure you’ve DM’d the bot at least once (so it can DM you back), and then restart the gateway.

Option B (no buttons): forward approvals into a Discord DM/channel and approve with /approve

Your current block:

approvals: { exec: { mode:"targets", targets:[...] } }

is the forwarding system. On Discord it won’t show buttons; you approve with:

  • /approve <id> allow-once
  • /approve <id> allow-always
  • /approve <id> deny