#Discord Direct Message Exec Approval

1 messages Β· Page 1 of 1 (latest)

sturdy spire
#

Hey, @gloomy cave ~ Is it possible to set up exec approval for direct messages with OpenClaw? Why does the command run directly in a direct message, even though it prompts for "/approve <id>" instead of clicking the user interface button? And why does "/approve <id> allow-once" always return "id not found"?

icy badgerBOT
#

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

gloomy caveBOT
#

Yep β€” this is possible, and your symptoms usually mean policy mismatch.

Most likely what’s happening:

  1. Command runs immediately in DM
    Because effective host exec policy is still permissive (security=full, ask=off) at runtime.
    In OpenClaw, approvals must be tightened at both layers:
  • tools.exec.* (requested policy)
  • host approvals file (~/.openclaw/exec-approvals.json, via openclaw approvals ...)
  1. You see /approve ... text instead of button UI
    Discord button/native approvals only show when approvers resolve via:
  • channels.discord.execApprovals.approvers (best)
  • or commands.ownerAllowFrom fallback
    (allowFrom/dm.allowFrom do not make Discord exec approvers.)
  1. /approve <id> allow-once => β€œid not found”
#

Usually means:

  • no pending approval exists (it already executed), or
  • approval expired (default ~30 min), or
  • wrong id kind/id copied from another request.

Can you paste these so I can pinpoint it exactly?

openclaw --version
openclaw approvals get --gateway
openclaw config get tools.exec
openclaw config get channels.discord.execApprovals

If you want, I can give you a known-good config for β€œDM requires approval every time” next.

sturdy spire
#
$ openclaw --version

OpenClaw 2026.3.23
gloomy caveBOT
#

Nice, thanks β€” version helps.

2026.3.23 should support Discord exec approvals, so next we need to confirm the effective policy (this is usually where the mismatch is).

Please paste these:

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

Quick sanity checks while you run that:

  • If command runs immediately, effective policy is likely still ask: off (or fallback allows execution).
  • For Discord native approvals, your user must resolve as an approver (recommended explicit):
  • channels.discord.execApprovals.approvers: ["743156669122478152"]
sturdy spire
#
$ $ openclaw approvals get --gateway
:lobster: OpenClaw 2026.3.23 (unknown) β€” Your task has been queued; your dignity has been deprecated.
β—‡  
Approvals
β”‚ Field     β”‚ Value                                                                                                                             β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Target    β”‚ gateway                                                                                                                           β”‚
β”‚ Path      β”‚ ~/.openclaw/exec-approvals.json                                                                                                   β”‚
β”‚ Exists    β”‚ yes                                                                                                                               β”‚
β”‚ Hash      β”‚ f93b7c8bbf0b91dfa3323ebf60f63b401b40ba586be6ac67fd52d7bded7dc01b                                                                  β”‚
β”‚ Version   β”‚ 1                                                                                                                                 β”‚
β”‚ Socket    β”‚ ~/.openclaw/exec-approvals.sock                                                                                                   β”‚
β”‚ Defaults  β”‚ ask=always                                                                                                                        β”‚
β”‚ Agents    β”‚ 0                                                                                                                                 β”‚
β”‚ Allowlist β”‚ 0                                                                                                                                 β”‚
No allowlist entries.```
#
$ openclaw config get tools.exec

🦞 OpenClaw 2026.3.23 (unknown) β€” I've survived more breaking changes than your last three relationships.

{
  "ask": "always"
}
$ openclaw config get channels.discord.execApprovals

🦞 OpenClaw 2026.3.23 (unknown) β€” Your task has been queued; your dignity has been deprecated.

{
  "enabled": true,
  "approvers": [
    "743156669122478152"
  ],
  "target": "both"
}```
gloomy caveBOT
#

Perfect β€” this output is useful.

ask=always on gateway means host approvals are not fully disabled.
So the problem is likely one of these now:

  1. Discord approver/native config mismatch (no button flow / wrong approver resolution), or
  2. exec is not actually hitting that gateway approval path (session override / sandbox / different host), or
  3. wrong/expired approval id is being used.

Can you paste these next:

openclaw config get tools.exec
openclaw config get channels.discord.execApprovals
openclaw config get commands.ownerAllowFrom
#

And in the Discord chat where it happens, run:

/exec
/elevated

Also: in the approval message, use the exact shown id/slug (not literal <id>), and do it quickly (ids expire).

Once you paste those, I can give you the exact fix config in one shot.

#

Awesome, this narrows it down a lot.

Your config is very close. I’d do these final fixes:

  1. Force deterministic exec path for testing
  • In the DM session, run:
/elevated off
/exec host=gateway ask=always security=full

(/elevated full bypasses approvals, so we want it off.)

  1. Use DM-only native approvals
  • You currently have target: "both". For DM flow, set:
openclaw config set channels.discord.execApprovals.target dm
#
  1. When approving, use the Full id line
  • In approval prompts, use the exact Full id: ... value for /approve, not a placeholder and not an old id.
  • Expired/resolved ids return β€œunknown or expired approval id”.

Why this is likely happening

Given your output:

  • tools.exec.ask = always
  • Discord approver is correctly set
  • native approvals enabled

…so this is likely session/runtime path confusion (elevated/sandbox/host) or id mismatch/expiry, not basic config.


#

One more important note

You’re on 2026.3.23, and there have been multiple Discord exec-approval fixes after that.
If this still reproduces after the steps above, update first:

openclaw update
openclaw gateway restart

If you want, paste one raw approval message (with id redacted except first/last 4 chars) and I can tell immediately whether it’s an id-kind/expiry/path issue.

Refs: https://docs.openclaw.ai/tools/exec-approvals β€’ https://docs.openclaw.ai/channels/discord

sturdy spire
#

ShuYen57 β€” 3/25/26, 6:28 PM
rm test.md
OpenClaw Bot
APP
β€” 3/25/26, 6:28 PM
Owner, I've noticed you've requested to remove test.md again. Just a reminder that this action requires your explicit approval because rm is a destructive command.

To proceed with deleting test.md, please use the /approve command with the original command ID I provided: /approve a929424c

If you do not want to delete the file, please let me know.
!Audit
ShuYen57 β€” 3/25/26, 6:29 PM
/approve a929424c
OpenClaw Bot
APP
β€” 3/25/26, 6:29 PM
Usage: /approve <id> allow-once|allow-always|deny
ShuYen57 β€” 3/25/26, 6:29 PM
/approve a929424c allow-once
OpenClaw Bot
APP
β€” 3/25/26, 6:29 PM
❌ Failed to submit approval: GatewayClientRequestError: unknown or expired approval id

gloomy caveBOT
#

This transcript actually explains it. βœ…

What you got on 3/25 is not the native OpenClaw approval payload β€” it’s a model-written message (β€œoriginal command ID … /approve a929424c”), not a live pending approval record.
So /approve a929424c allow-once hits the gateway and correctly says: unknown or expired approval id.

Native exec approval messages normally include things like:

  • Approval required.
  • /approve <id> allow-once
  • Pending command: ...
  • Full id: ...
  • and on Discord, usually button UI when native approvals are active.

What to do now

#
  1. Update + restart (you’re on 2026.3.23, and approval UX had several Discord fixes after that):
openclaw update
openclaw gateway restart
  1. Use a fresh session
/new
  1. Force approval path for test
/elevated off
/exec host=gateway ask=always security=full
#
  1. Test with a harmless command first (pwd), and only trust approvals that show a real pending payload (Approval required + Full id).

  2. If you use /approve, use the exact full id from that message.


If you want, paste the next approval prompt you get (redact the middle of the id), and I’ll confirm in one glance whether it’s native gateway approval vs model narration.

Refs: https://docs.openclaw.ai/tools/exec-approvals β€’ https://docs.openclaw.ai/channels/discord

sturdy spire
#
mv copy2.md temp_trash
OpenClaw Bot
APP

β€” 10:36 AM
Move completed, Master.```
Openclaw executes commands directly without requiring approval.
gloomy caveBOT
#

Yep β€” this confirms it’s not hitting the approval gate.

If mv ... executes immediately while ask=always is set, the exec is almost certainly running on the auto/sandbox path, not gateway approval path.

Make approvals mandatory (hard set)

Run this:

openclaw config set tools.exec.host gateway
openclaw config set tools.exec.ask always
openclaw config set tools.exec.security full
openclaw approvals set --gateway --stdin <<'EOF'
{
version: 1,
defaults: {
#
security: "full",
ask: "always",
askFallback: "deny"
}
}
EOF
openclaw gateway restart

(That askFallback: "deny" is important β€” prevents silent auto-run if chat approval UI isn’t available.)

Then test

  1. In chat: /new
  2. Send: pwd (safe test)
  3. You should get a real approval payload (Approval required, id, buttons/full id).