#Agent doesn't update anymore

1 messages Β· Page 1 of 1 (latest)

rare lotusBOT
vale dirgeBOT
#

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

rare lotusBOT
chilly wagonBOT
#

That failure was the exec approval layer, not the updater itself.

What happened:

  • the command never actually ran
  • this Discord thread is not acting as a native exec approval client
  • so your Approved message here did not attach to the pending terminal command
  • because it also wasn’t allowlisted, OpenClaw denied it with approval-timeout (allowlist-miss)

Best next step, run this locally in your terminal:

openclaw --version
openclaw update
openclaw doctor

If openclaw update is unavailable for your install, use:

rocky horizon
#

I used to be able to update openclaw by just telling my agent in my telegram to just update itself. Now it doesnt work anymore. Why? Is this a new thing?

chilly wagonBOT
#

Yeah, kind of, this is usually the newer exec-approvals behavior, not the updater itself breaking.

What changed in practice:

  • a self-update is host exec
  • host exec now obeys the effective exec approval policy
  • if the command is not allowlisted, and approval can’t be resolved, it gets denied
  • plain chat text like β€œApproved” does not count as an approval path

Current supported path is usually:

  • native approval UI/buttons, or
  • same-chat /approve from an authorized approver

So if it used to work from Telegram, one of these likely changed:

  1. your OpenClaw version changed and exec approvals got stricter
  2. your approver mapping no longer resolves (allowFrom / owner / execApprovals)
  3. the host approvals policy is no longer effectively full + ask off
#

If you want, I can help interpret the approvals get output once you paste it.

rocky horizon
#

openclaw approvals get
openclaw status
OpenClaw 2026.4.9 (0512059)

🦞 OpenClaw 2026.4.9 (0512059) β€” I don't have opinions about tabs vs spaces. I have opinions about everything else.

Showing local approvals.

Approvals
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Field β”‚ Value β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Target β”‚ local β”‚
β”‚ Path β”‚ ~/.openclaw/exec-approvals.json β”‚
β”‚ Exists β”‚ yes β”‚
β”‚ Hash β”‚ d5c4d303dfe890711d2f65c036e0b3395c25b4fae4383962275125803732f08c β”‚
β”‚ Version β”‚ 1 β”‚
β”‚ Socket β”‚ ~/.openclaw/exec-approvals.sock β”‚
β”‚ Defaults β”‚ none β”‚
β”‚ Agents β”‚ 0 β”‚
β”‚ Allowlist β”‚ 0 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

No allowlist entries.

chilly wagonBOT
#

Yep, that pretty much explains it.

On 2026.4.9, your agent is no longer in a β€œjust run host commands freely” setup.

From what you pasted:

  • no allowlist entries
  • no approvals defaults
  • the update command hit allowlist-miss
  • and plain β€œApproved” in chat was not a valid exec approval

So yes, compared to the old self-updating-from-chat behavior, this is effectively a stricter exec approvals path.

What that means

A command like updating the global install is treated as host exec now.
If it is not explicitly allowed, OpenClaw needs a real approval path:

  • /approve from an authorized approver, or
  • native approval UI/buttons, or
#
  • a looser host policy

Best options

1. Easiest / recommended

openclaw update

2. Keep approvals, but make chat updates work again
Set up proper exec approvals for Telegram/Discord so /approve or native approval delivery works reliably.

3. Restore the old β€œjust do it” behavior on that machine

openclaw exec-policy preset yolo
rocky horizon
#

openclaw exec-policy show
error: unknown command 'exec-policy'

chilly wagonBOT
#

Sorry, that one’s on me, exec-policy is from a newer build than 2026.4.9.

So the useful part here is simpler:

  • your update command was denied with allowlist-miss
  • your local approvals store has no allowlist entries
  • plain β€œApproved” in chat did not count as a real exec approval

So yes, this is basically a newer/stricter approval behavior compared to the old β€œagent just updates itself” flow.

What to do now

Fastest path

openclaw update
#

If that doesn’t work for your install:

pnpm add -g openclaw@latest

If you want to debug the approval side on your current version

Run:

openclaw approvals --help
openclaw status --all

The first tells us what approval commands your installed version actually supports.
The second may show the active exec/tool policy that caused the deny.

So short answer: yes, behavior changed, and your current setup is no longer allowing self-update-through-chat without a proper exec approval path.

rocky horizon
#

what are my options? how can i tell openclaw that approvals from telegram are good?

chilly wagonBOT
#

You’ve basically got 3 paths:

1. Easiest

Update locally when needed:

openclaw update

2. Recommended

Keep approvals on, but make Telegram a trusted approval client.

3. Least safe

Turn host exec into β€œjust run it” mode again. I wouldn’t recommend that unless you really want zero approval friction.


To make Telegram approvals count

#

OpenClaw needs to know which Telegram user ID is allowed to approve.

Step 1: get your Telegram numeric user ID

In Telegram, DM your bot and run:

/whoami

(or /id)

Step 2: put that ID in config

Minimal JSON5 example:

{
#
  channels: {
    telegram: {
      allowFrom: ["123456789"],
      defaultTo: "123456789",
      execApprovals: {
        enabled: true,
        approvers: ["123456789"],
        target: "dm"
      }
    }
  }
}

Replace 123456789 with your real Telegram user ID.

#

What those do

  • allowFrom: says you’re an allowed Telegram sender
  • defaultTo: helps OpenClaw resolve the owner DM
  • execApprovals.approvers: explicitly says this Telegram user can approve exec
  • target: "dm": send approval prompts to your Telegram DM

If you want approval prompts in the same Telegram chat/topic too, use:

target: "both"

Step 3: restart the gateway

openclaw gateway restart

Step 4: retry

#

If you want, paste your current channels.telegram block and I’ll rewrite it into the exact JSON5 you need.

#

Yes, that’s the right config block, but first, please rotate that Telegram bot token right now. You pasted it in a public thread.

After rotating it in BotFather, use one of these.

Minimal change

Keeps your current pairing setup, but explicitly trusts Telegram approvals from your numeric Telegram user ID:

{
  channels: {
    telegram: {
      enabled: true,
      dmPolicy: "pairing",
      botToken: "<NEW_TELEGRAM_BOT_TOKEN>",
      groupPolicy: "allowlist",
      defaultTo: "<YOUR_TELEGRAM_USER_ID>",
#
      execApprovals: {
        enabled: true,
        approvers: ["<YOUR_TELEGRAM_USER_ID>"],
        target: "dm",
      },
      streaming: {
        mode: "off",
      },
    },
  },
}

Better / more durable

For a one-owner bot, I’d actually recommend this:

#
{
  channels: {
    telegram: {
      enabled: true,
      dmPolicy: "allowlist",
      allowFrom: ["<YOUR_TELEGRAM_USER_ID>"],
      defaultTo: "<YOUR_TELEGRAM_USER_ID>",
      botToken: "<NEW_TELEGRAM_BOT_TOKEN>",
      groupPolicy: "allowlist",
      execApprovals: {
        enabled: true,
        approvers: ["<YOUR_TELEGRAM_USER_ID>"],
        target: "dm",
      },
      streaming: {
#
        mode: "off",
      },
    },
  },
}

How to get your Telegram user ID

DM your bot:

/whoami

Then use that numeric ID in allowFrom, defaultTo, and approvers.

#

After editing config

openclaw gateway restart

Then test again. Approval prompts should go to your Telegram DM, and you can approve with the buttons or /approve <id> allow-once.

Also, since the token is exposed here, I’d delete/edit that Discord message after rotating it.

rocky horizon
#

how do i rotate the exposed telegram bot token? give me the steps?

chilly wagonBOT
#

Yep. Do this now, in order:

  1. Open Telegram

    • make sure you’re using the account that owns the bot
  2. Open @BotFather

  3. Revoke the current token

    • easiest path: send
      /revoke
      
    • then pick your bot

    Alternative UI path:

    • /mybots
    • select your bot
#
  • API Token
    • Revoke Current Token
  1. Generate/get the new token

    • BotFather will give you a fresh token after revoke
    • if needed, use:
      /token
      
      and pick the same bot
  2. Replace the old token in your OpenClaw config

    • update channels.telegram.botToken with the new one
  3. Restart OpenClaw

#
   openclaw gateway restart
  1. Test the bot

    • DM the bot in Telegram
    • send something simple like /whoami
    • make sure it responds
  2. Clean up exposure

    • edit/delete the Discord message where the token was pasted
    • remove it from any screenshots, notes, or logs you shared

Important bit: once you revoke, the old token should stop working, which is exactly what you want.

If you want, paste your config again with the token redacted, and I’ll help you wire in the Telegram exec approvals next.

rocky horizon
#

okay, i got the new bot token, now what do i do?

chilly wagonBOT
#

Nice, next do this:

1. Put the new token into your config

In ~/.openclaw/openclaw.json, replace the old Telegram token with the new one under:

channels.telegram.botToken

For now, keep the rest as-is.

2. Restart the gateway

openclaw gateway restart

3. Test that Telegram is alive again

#

DM your bot and run:

/whoami

That should give you your numeric Telegram user ID.

4. Then update your Telegram config to trust your approvals

Once you have that ID, I’d change your block to this:

{
  channels: {
    telegram: {
      enabled: true,
#
      dmPolicy: "allowlist",
      allowFrom: ["<YOUR_TELEGRAM_USER_ID>"],
      defaultTo: "<YOUR_TELEGRAM_USER_ID>",
      botToken: "<NEW_TELEGRAM_BOT_TOKEN>",
      groupPolicy: "allowlist",
      execApprovals: {
        enabled: true,
        approvers: ["<YOUR_TELEGRAM_USER_ID>"],
        target: "dm",
      },
      streaming: {
        mode: "off",
      },
    },
  },
#
}

5. Restart again

openclaw gateway restart

6. Test approvals

From Telegram, ask the agent to run something small that needs exec.
You should get an approval prompt in Telegram DM, then approve with the button or:

/approve <id> allow-once
#

If you want, paste your Telegram user ID and I’ll fill that block out exactly, with the token still redacted.

rocky horizon
#

how do i get the telegram user id in the json too?

chilly wagonBOT
#

You don’t get your Telegram user ID from the JSON itself, it’s a separate value.

Use this flow:

1. First, put only the new bot token in config

Update:

channels.telegram.botToken

2. Restart the gateway

openclaw gateway restart

3. DM your bot in Telegram and run

#
/whoami

(or /id)

That reply should show your numeric Telegram user ID.

4. Copy that number into the JSON

Example, if /whoami returns 123456789:

allowFrom: ["123456789"],
defaultTo: "123456789",
execApprovals: {
  enabled: true,
#
  approvers: ["123456789"],
  target: "dm",
},

Important:

  • use your personal Telegram user ID
  • not the bot username
  • not the bot token
  • not the bot’s own id

So the practical order is:

  1. new bot token in config
  2. restart
  3. /whoami
#
  1. paste that number into config
  2. restart again

If you want, I can show you the exact final Telegram block with placeholders in the right spots.

rocky horizon
#

is it fine for the bot token thaat the first numbers before the colon is the same as the old one?

chilly wagonBOT
#

Yes, that’s normal.

  • the number before the colon is basically the bot’s ID, so it can stay the same
  • the secret part after the colon is the part that changes when you rotate the token

So if the prefix stayed the same but the rest changed, that’s fine.

Just make sure:

  • you replaced the old token everywhere with the new one
  • you don’t paste the new token publicly
  • then restart:
openclaw gateway restart

After that, test the bot in Telegram.

rocky horizon
#

how do i update it now from the chat?

chilly wagonBOT
#

Once the Telegram config is in place, the chat flow is:

1. Finish config and restart

Make sure your Telegram block has:

  • new botToken
  • your Telegram user ID in allowFrom
  • your Telegram user ID in defaultTo
  • execApprovals configured

Then:

openclaw gateway restart

2. Use Telegram for the update request

DM your bot and say something like:

#
run openclaw update

or just:

update yourself

3. Approve it properly

When the approval prompt shows up, use:

  • the approval button, or
  • the command:
    /approve <id> allow-once
    
#

Important: plain β€œApproved” is not enough.

4. Verify after update

Ask it to run:

openclaw --version

or check locally in terminal:

openclaw --version

One useful detail

If your config has:

#
target: "dm"

the approval prompt may show up in your Telegram DM, even if the original request came from somewhere else.

If you want, I can give you the exact final Telegram config block one more time, with placeholders only.

rocky horizon
#

i asked it to update and it still says it cant from the telegram session because the exec approval path for elevated global install commands isnt available here

chilly wagonBOT
#

Ah, I think we were only fixing half of it.

For chat-driven updates, there are two separate gates:

  1. Elevated mode: Telegram must be allowed to request host-side commands
  2. Exec approvals: Telegram must be allowed to approve the command

You already started on #2. You probably still need #1.

Add this too

{
  tools: {
    elevated: {
      enabled: true,
#
      allowFrom: {
        telegram: ["<YOUR_TELEGRAM_USER_ID>"],
      },
    },
  },

  channels: {
    telegram: {
      enabled: true,
      dmPolicy: "allowlist",
      allowFrom: ["<YOUR_TELEGRAM_USER_ID>"],
      defaultTo: "<YOUR_TELEGRAM_USER_ID>",
      botToken: "<NEW_TELEGRAM_BOT_TOKEN>",
      groupPolicy: "allowlist",
      execApprovals: {
#
        enabled: true,
        approvers: ["<YOUR_TELEGRAM_USER_ID>"],
        target: "dm",
      },
      streaming: {
        mode: "off",
      },
    },
  },
}

Then restart

openclaw gateway restart
#

Then in Telegram

First enable elevated for the session:

/elevated on

Then ask it to update:

run openclaw update

When the approval prompt appears, approve it with:

  • the button, or
  • /approve <id> allow-once
rocky horizon
#

i want to be able to just casually tell my agent to update using the chat and have it update. i dont want to run any specific commands or /commands. i want it to be casual

chilly wagonBOT
#

Got it. What you want is possible, but there’s a real tradeoff here.

Two ways to make it feel casual

Option 1, my recommendation

You say something natural like:

update yourself
update OpenClaw
grab the latest version

And then you get one approval button in Telegram to tap.

That means:

  • no /elevated
  • no /approve unless the button fails
  • still keeps a safety check before host/global install commands
#

To get that feel, you want:

  • Telegram set up as the exec approval client
  • your Telegram ID in tools.elevated.allowFrom.telegram
  • your Telegram ID in channels.telegram.execApprovals.approvers
  • agents.defaults.elevatedDefault effectively on/ask for that agent

Option 2, fully casual / zero approval taps

You just say:

update yourself

…and it runs immediately.

That only works if you turn off or greatly relax the approval gates for host exec on that machine. It’s doable, but it is genuinely less safe.


#

Honest answer

If you want it to be casual but still sane, the best setup is:

  • natural language request
  • one Telegram approval tap
  • no slash commands

If you want it to be casual with no approval step at all, then you’re asking for YOLO/full host exec.

If you want, I can help you set up Option 1 first, which is usually the sweet spot.
If that still feels too annoying, then I can explain the zero-approval version next.

rocky horizon
#

i want fully casual no approval taps

chilly wagonBOT
#

Okay, that’s the YOLO / no-approval setup.

I’m a little nervous recommending it casually, because it means your Telegram chat can trigger host commands without approval prompts. But if it’s your private bot and you want that tradeoff, this is the shape of it.

1. Open host exec fully

In your openclaw.json, you want the agent allowed to run host exec without approval stops:

{
  tools: {
    exec: {
      host: "gateway",
      security: "full",
      ask: "off",
    },
    elevated: {
#
      enabled: true,
      allowFrom: {
        telegram: ["<YOUR_TELEGRAM_USER_ID>"],
      },
    },
  },
  agents: {
    defaults: {
      elevatedDefault: "full",
    },
  },
  channels: {
    telegram: {
      enabled: true,
      dmPolicy: "allowlist",
#
      allowFrom: ["<YOUR_TELEGRAM_USER_ID>"],
      defaultTo: "<YOUR_TELEGRAM_USER_ID>",
      botToken: "<NEW_TELEGRAM_BOT_TOKEN>",
      groupPolicy: "allowlist",
      streaming: {
        mode: "off",
      },
    },
  },
}

2. Open the host approvals file too

This is the second layer. Edit:

#
~/.openclaw/exec-approvals.json

and make sure it contains defaults like:

{
  version: 1,
  defaults: {
    security: "full",
    ask: "off",
    askFallback: "full",
  },
}
#

If this file stays stricter, it will still block you even if openclaw.json looks open.

3. Restart

openclaw gateway restart

4. Then your chat can be casual

At that point, you should be able to say things like:

update yourself
update OpenClaw
grab the latest version

and it should just run, no approval tap.

Strong warning

#

If you do this, keep it tight:

  • only your Telegram user ID in allowFrom
  • avoid shared/public chats for control
  • keep groupPolicy: "allowlist" or even disable group control entirely

If you want, paste your current config with secrets redacted and I’ll turn it into the exact zero-approval version for your setup.

rocky horizon
#

"agents": {
"defaults": {
"model": {
"primary": "openai-codex/gpt-5.4",
"fallbacks": [
"openai-codex/gpt-5.3-codex"
]
},
"models": {
"openai-codex/gpt-5.4": {}
},
"workspace": "",
"compaction": {
"mode": "safeguard"
},
"heartbeat": {
"every": "90m",
"target": "last",
"lightContext": true
},
"maxConcurrent": 4,
"subagents": {
"maxConcurrent": 8
},
"elevatedDefault": "full",
}

like this?

chilly wagonBOT
#

Yes, that is the right place for:

elevatedDefault: "full"

So that part looks right.

But, important, that line alone will not give you zero-approval chat updates. It’s only one piece.

You still also need:

1. tools.elevated

Telegram must be allowed to request elevated/host exec:

#
tools: {
  elevated: {
    enabled: true,
    allowFrom: {
      telegram: ["<YOUR_TELEGRAM_USER_ID>"],
    },
  },
}

2. tools.exec

Host exec itself must be opened up:

tools: {
#
  exec: {
    host: "gateway",
    security: "full",
    ask: "off",
  },
}

3. host approvals file

~/.openclaw/exec-approvals.json must also be open, otherwise it can still block you:

{
  version: 1,
  defaults: {
#
    security: "full",
    ask: "off",
    askFallback: "full",
  },
}

4. Telegram access

Your Telegram user ID still needs to be trusted in the Telegram section.

So: yes, that snippet is correct, but it is not sufficient by itself.

If you want, paste your full config with secrets redacted and I’ll mark exactly where each piece goes.

rocky horizon
#

this looks good for the tools section?:

"tools": {
"profile": "full",
"sessions": {
"visibility": "all"
},
"elevated": {
"enabled": true,
"allowFrom": {
"telegram": ["<YOUR_TELEGRAM_USER_ID>"],
},
},
"exec": {
"host": "gateway",
"security": "full",
"ask": "off",
}
},

chilly wagonBOT
#

Yep, that looks basically right for the tools part.

A couple notes:

  • profile: "full" and sessions.visibility: "all" are not what makes the update work
  • the important bits here are:
elevated: {
  enabled: true,
  allowFrom: {
    telegram: ["<YOUR_TELEGRAM_USER_ID>"],
  },
},
exec: {
  host: "gateway",
#
  security: "full",
  ask: "off",
},

So yes, those are the key settings for the no-approval behavior.

Still required beyond this

You also still need:

  1. agents.defaults.elevatedDefault: "full"
  2. your Telegram section with your real Telegram user ID
  3. ~/.openclaw/exec-approvals.json opened up too

Tiny reminder

Replace:

#
"<YOUR_TELEGRAM_USER_ID>"

with your actual numeric Telegram user ID.

If you’ve got the agents block and the channels.telegram block too, paste those redacted and I’ll do one final sanity check.

chilly wagonBOT
#

That error confirms the restart wasn’t the real fix.

What broke:

  • one compiled dist file is importing another hashed dist file that no longer exists
  • that’s a partial / mismatched global install
  • so restart alone won’t fix it

In plain English, OpenClaw’s installed files are out of sync.

Best fix

Repair the install locally once.

Try this first

openclaw update
openclaw doctor
#
openclaw gateway restart
openclaw status

If openclaw update still trips over the broken install

Re-run the installer instead:

curl -fsSL https://openclaw.ai/install.sh | bash
openclaw doctor
openclaw gateway restart
openclaw status

After that, check:

rocky horizon
#

Self update flow works. The problem was that the cron job didnt run this morning

chilly wagonBOT
#

Yep, that changes the diagnosis.

If the self-update flow works now, then the cron issue was probably not β€œTelegram approvals” at all.

Most likely what happened:

  • the cron did fire
  • but that morning run hit the half-broken global install
  • it crashed with ERR_MODULE_NOT_FOUND before it could send the weather message

So the problem was likely the runtime/import failure during the cron run, not the cron schedule itself.

Best next check

Force-run the cron once now and inspect the recent runs:

openclaw cron run morning-weather-briefing
#
openclaw cron runs --id morning-weather-briefing --limit 20

If that manual run succeeds now, tomorrow’s scheduled run should probably be fine too.

Short version

  • Self-update path: seems okay now
  • Cron miss this morning: likely happened while OpenClaw was in that broken install state
  • Not necessarily a cron config bug

Docs:

If you paste the output of openclaw cron runs --id morning-weather-briefing --limit 20, I can tell you pretty quickly whether it’s fixed or still flaky.