Skip to content

[Bug]: Elevated exec fails after approval callback in 2026.4.26 #74646

Description

@jameyedwards

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

  1. Configure elevated exec for Telegram:
{
"tools": {
"elevated": {
"enabled": true,
"allowFrom": {
"telegram": ["*"]
}
}
}
}
  1. From a Telegram direct chat, trigger any elevated exec:
User: "check the system logs"
Agent calls exec with elevated: true
  1. OpenClaw sends an approval card to Telegram with inline buttons
    (Allow Once / Allow Always / Deny).

  2. 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

  1. 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.

  2. 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.

  3. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingbug:behaviorIncorrect behavior without a crash

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions