Bug type
Behavior bug (incorrect output/state without crash)
Beta release blocker
No
Summary
Elevated exec commands that require interactive approval (via Telegram inline buttons) fail on the followup run after the user approves. The sendExecApprovalFollowup spawned run does not inherit the provider context from the originating Telegram session, causing the elevated permission check to fail with provider=null.
This makes elevated exec unusable in any flow that requires approval — which is the default for most elevated commands.
Steps to reproduce
- Configure elevated exec for Telegram:
{
"tools": {
"elevated": {
"enabled": true,
"allowFrom": {
"telegram": ["*"]
}
}
}
}
- From a Telegram direct chat, trigger any elevated exec:
User: "check the system logs"
Agent calls exec with elevated: true
-
OpenClaw sends an approval card to Telegram with inline buttons
(Allow Once / Allow Always / Deny).
-
User taps "Allow Once."
Expected behavior
The command executes with elevated privileges and returns output to the agent.
Actual behavior
The approval followup run fails with:
elevated is not available right now (runtime=sandboxed).
Failing gates: enabled (tools.elevated.enabled / agents.list[].tools.elevated.enabled)
Context: provider=telegram session=agent:main:telegram:direct:<chat_id>
The agent receives no output. The session resume also fails, and the raw error + internal context is dumped to the Telegram chat with an "Automatic session resume failed" prefix.
OpenClaw version
OpenClaw 2026.4.26 (be8c246)
Operating system
Ubuntu 24.04, Docker sandbox, Telegram channel
Install method
npm global
Model
Anthropic Opus 4-6
Provider / routing chain
/usr/bin/openclaw -> ../lib/node_modules/openclaw/openclaw.mjs
Additional provider/model setup details
User taps "Allow Once" on Telegram inline button
→ Telegram callback_query arrives at Gateway
→ Gateway calls sendExecApprovalFollowup
→ Followup spawns a new agent run (provider=null ← BUG)
→ Elevated check: allowFrom[???] — no provider to match
→ Fails with "elevated is not available"
→ Session resume fails
→ Raw error dumped to Telegram
Logs, screenshots, and evidence
## Root Cause Analysis
Three related code paths contribute to elevated exec flapping. Root
cause #3 is the one introduced/worsened in 2026.4.26:
### Root Cause 1 — `compact.ts` hardcodes elevated off
- After context compaction, `compact.ts` hardcodes `bashElevated:
{enabled: false, allowed: false}`
- Any elevated exec attempted after compaction will fail
- **Related issue:** #18834
### Root Cause 2 — `agent-runner-memory.ts` hardcodes elevated off for
heartbeat/fast-directive
- Heartbeat and fast-directive runs set `elevatedAllowed: false`
- Elevated exec during heartbeat-triggered work fails
- **Related issue:** #30379
### Root Cause 3 — Approval followup runs don't inherit provider
context (PRIMARY BUG)
- When `sendExecApprovalFollowup` spawns a new agent run to deliver
the approved command's output, the spawned run has `provider = null`
- The 2026.4.26 elevated permission check now hard-requires a known
provider before evaluating `allowFrom`
- With `provider = null`, no `allowFrom` entry can match —
`allowFrom.telegram: ["*"]` doesn't help because the check never
reaches the telegram key
- **Related issue:** #40034
### Deterministic pattern:
- `provider=telegram` (direct user message triggers exec) → **elevated works** ✅
- `exec-approval-followup` (spawned after user taps approve button) →
**elevated fails** ❌
- The flapping appears random but is actually deterministic based on
which code path triggered the run
Impact and severity
-
Session resume leak: When the followup run fails, the error recovery path dumps raw internal context to the Telegram chat, including tool call metadata and error traces.
-
Sandbox state loss: The sandbox container appears to get recycled during the failed followup, causing mounted files (e.g.,.hook-auth) to intermittently disappear. Subsequent exec calls in the same session fail with FileNotFoundError until the container stabilizes.
-
Inconsistent elevated availability: Within a single conversation, some elevated calls work (user-initiated) and some don't (approval-followup), making the feature appear unreliable.
Additional information
Workarounds Attempted
| Workaround |
Result |
allowFrom.telegram: ["*"] |
Doesn't help — provider is null in |
| followup, never reaches telegram key |
|
allowFrom.telegram: ["8676994316"] |
Same — null provider |
Local source patch of get-reply-*.js to hardcode `elevatedEnabled: |
|
| true` |
Fixes direct runs but not approval followup runs (separate |
| code path) |
|
Patching compact.ts and agent-runner-memory.ts |
Fixes root |
| causes 1 and 2 but not 3 |
|
No config-level workaround exists for root cause #3.
Suggested Fix
sendExecApprovalFollowup should propagate the originating session's
provider context (and channel metadata) to the spawned followup run.
The followup run should inherit:
provider (e.g., "telegram")
senderId (the user who approved)
channelId / chatId
This would allow the elevated permission check to correctly evaluate
allowFrom in the followup path.
Environment Details
- OS: Ubuntu 24.04 (6.8.0-110-generic, x64)
- Node: v22.22.1
- OpenClaw: 2026.4.26 (be8c246)
- Sandbox: Docker-based, workspace mounted rw
- Channel: Telegram (direct chat)
- Agent: main (Claude Opus 4-6)
- Elevated config:
tools.elevated.enabled: true,
allowFrom.telegram: ["*"]
Related Issues
Bug type
Behavior bug (incorrect output/state without crash)
Beta release blocker
No
Summary
Elevated exec commands that require interactive approval (via Telegram inline buttons) fail on the followup run after the user approves. The
sendExecApprovalFollowupspawned run does not inherit the provider context from the originating Telegram session, causing the elevated permission check to fail withprovider=null.This makes elevated exec unusable in any flow that requires approval — which is the default for most elevated commands.
Steps to reproduce
{ "tools": { "elevated": { "enabled": true, "allowFrom": { "telegram": ["*"] } } } }OpenClaw sends an approval card to Telegram with inline buttons
(Allow Once / Allow Always / Deny).
User taps "Allow Once."
Expected behavior
The command executes with elevated privileges and returns output to the agent.
Actual behavior
The approval followup run fails with:
The agent receives no output. The session resume also fails, and the raw error + internal context is dumped to the Telegram chat with an "Automatic session resume failed" prefix.
OpenClaw version
OpenClaw 2026.4.26 (be8c246)
Operating system
Ubuntu 24.04, Docker sandbox, Telegram channel
Install method
npm global
Model
Anthropic Opus 4-6
Provider / routing chain
/usr/bin/openclaw -> ../lib/node_modules/openclaw/openclaw.mjs
Additional provider/model setup details
User taps "Allow Once" on Telegram inline button
→ Telegram callback_query arrives at Gateway
→ Gateway calls sendExecApprovalFollowup
→ Followup spawns a new agent run (provider=null ← BUG)
→ Elevated check: allowFrom[???] — no provider to match
→ Fails with "elevated is not available"
→ Session resume fails
→ Raw error dumped to Telegram
Logs, screenshots, and evidence
Impact and severity
Session resume leak: When the followup run fails, the error recovery path dumps raw internal context to the Telegram chat, including tool call metadata and error traces.
Sandbox state loss: The sandbox container appears to get recycled during the failed followup, causing mounted files (e.g.,
.hook-auth) to intermittently disappear. Subsequent exec calls in the same session fail withFileNotFoundErroruntil the container stabilizes.Inconsistent elevated availability: Within a single conversation, some elevated calls work (user-initiated) and some don't (approval-followup), making the feature appear unreliable.
Additional information
Workarounds Attempted
allowFrom.telegram: ["*"]allowFrom.telegram: ["8676994316"]get-reply-*.jsto hardcode `elevatedEnabled:compact.tsandagent-runner-memory.tsNo config-level workaround exists for root cause #3.
Suggested Fix
sendExecApprovalFollowupshould propagate the originating session'sprovider context (and channel metadata) to the spawned followup run.
The followup run should inherit:
provider(e.g., "telegram")senderId(the user who approved)channelId/chatIdThis would allow the elevated permission check to correctly evaluate
allowFromin the followup path.Environment Details
tools.elevated.enabled: true,allowFrom.telegram: ["*"]Related Issues