Bug Description
The agentCommand gateway RPC handler does not call resolveElevatedPermissions() and does not pass bashElevated to the embedded PI agent runner. This causes elevated exec to fail for all sessions dispatched via the gateway agent method, including sub-agents (sessions_spawn), sessions_send, and subagents steer.
Additionally, when a sub-agent fails elevated and announces back to the parent session, the parent's response to that announce also goes through the agentCommand path, causing the parent session's elevated to break until a new channel message (Telegram/BlueBubbles/Webchat) arrives and re-resolves permissions via Path A.
Environment
- OpenClaw version: 2026.2.15
- Platform: macOS (Darwin 24.6.0, Apple Silicon)
- Sandbox mode:
all (Docker)
- Agent config:
tools.elevated.enabled: true, agents.list[].tools.elevated.enabled: true, agents.defaults.elevatedDefault: "full", allowFrom: ["*"] at both levels
Steps to Reproduce
- Configure an agent with
sandbox.mode: "all" and tools.elevated.enabled: true at both global and agent levels
- Send a message via a channel (Telegram/BlueBubbles) — elevated works correctly
- Have the agent spawn a sub-agent via
sessions_spawn with a task that requires elevated exec
- Sub-agent attempts
elevated: true on an exec call → fails with:
elevated is not available right now (runtime=sandboxed).
Failing gates: enabled (tools.elevated.enabled / agents.list[].tools.elevated.enabled)
- Sub-agent announces failure back to parent
- Parent session attempts elevated exec in the context of processing the announce → also fails
- A new channel message (Telegram/iMessage) to the parent session restores elevated
Expected Behavior
- Sub-agents should have elevated resolved based on the parent agent's config (or explicitly disabled with a clear message)
- The parent session's elevated should never be affected by sub-agent operations
agentCommand should call resolveElevatedPermissions() the same way dispatchInboundMessage does
Root Cause Analysis
The Two Dispatch Paths
Path A — Channel messages (works correctly):
dispatchInboundMessage()
→ dispatchReplyFromConfig()
→ resolveElevatedPermissions(cfg, agentId, ctx, provider) ✅
→ bashElevated = { enabled: true, allowed: true, defaultLevel: "full" }
→ runReplyAgent()
→ runEmbeddedPiAgent({ bashElevated }) ✅
Path B — Gateway agent RPC (broken):
callGateway({ method: "agent" })
→ agentCommand(opts) ❌ NEVER calls resolveElevatedPermissions()
→ runAgentAttempt(params) ❌ NO bashElevated in params
→ runEmbeddedPiAgent({ bashElevated: undefined })
→ createExecTool({ elevated: undefined })
→ elevatedAllowed = false → gate check fails
Affected Code Locations (v2026.2.15)
agentCommand in dist/agent-ryGRIqHy.js (~line 443): Missing resolveElevatedPermissions() call
runAgentAttempt in dist/agent-ryGRIqHy.js (~line 375-441): Does not receive or pass bashElevated to runEmbeddedPiAgent
runEmbeddedPiAgent in dist/subagent-registry-kdTa9uwX.js (~line 58200): Passes params.bashElevated through correctly, but receives undefined
createExecTool in dist/subagent-registry-kdTa9uwX.js (~line 11180): When defaults.elevated is undefined, elevatedAllowed = false, gate check always fails
All Affected Callers
Every caller of callGateway({ method: "agent" }) hits this bug:
sessions_spawn (line ~26696) — sub-agent task spawn
sessions_send (line ~26329, 26352) — cross-session messaging
subagents steer (line ~17111) — steering existing sub-agents
runAgentStep (line ~25962) — internal agent step execution
- Sub-agent memory flush/compaction paths (lines ~27182, 59060, 59334)
Suggested Fix
Add resolveElevatedPermissions() to agentCommand:
// In agentCommand(), before calling runAgentAttempt:
const { enabled: elevatedEnabled, allowed: elevatedAllowed, failures } =
resolveElevatedPermissions({ cfg, agentId: sessionAgentId, ctx: runContext, provider: messageChannel });
const resolvedElevatedLevel = elevatedAllowed
? agentCfg?.elevatedDefault ?? "on"
: "off";
const bashElevated = {
enabled: elevatedEnabled,
allowed: elevatedAllowed,
defaultLevel: resolvedElevatedLevel ?? "off"
};
// Pass bashElevated to runAgentAttempt → runEmbeddedPiAgent
Alternatively, as defense-in-depth, createExecTool could fall back to resolving elevated from the live config when defaults.elevated is undefined.
Impact
This bug makes elevated access unreliable for any agent using sandbox.mode: "all" with sub-agents. The parent session's elevated breaks every time a sub-agent attempts and fails elevated, requiring a new channel message to restore it. This blocks automated/overnight workflows where no human is available to send a recovery message.
Workaround
Set sandbox.mode: "non-main" for the affected agent so the main session runs on the host and doesn't need elevated. Sub-agents remain sandboxed.
Bug Description
The
agentCommandgateway RPC handler does not callresolveElevatedPermissions()and does not passbashElevatedto the embedded PI agent runner. This causes elevated exec to fail for all sessions dispatched via the gatewayagentmethod, including sub-agents (sessions_spawn),sessions_send, andsubagents steer.Additionally, when a sub-agent fails elevated and announces back to the parent session, the parent's response to that announce also goes through the
agentCommandpath, causing the parent session's elevated to break until a new channel message (Telegram/BlueBubbles/Webchat) arrives and re-resolves permissions via Path A.Environment
all(Docker)tools.elevated.enabled: true,agents.list[].tools.elevated.enabled: true,agents.defaults.elevatedDefault: "full",allowFrom: ["*"]at both levelsSteps to Reproduce
sandbox.mode: "all"andtools.elevated.enabled: trueat both global and agent levelssessions_spawnwith a task that requires elevated execelevated: trueon an exec call → fails with:Expected Behavior
agentCommandshould callresolveElevatedPermissions()the same waydispatchInboundMessagedoesRoot Cause Analysis
The Two Dispatch Paths
Path A — Channel messages (works correctly):
Path B — Gateway
agentRPC (broken):Affected Code Locations (v2026.2.15)
agentCommandindist/agent-ryGRIqHy.js(~line 443): MissingresolveElevatedPermissions()callrunAgentAttemptindist/agent-ryGRIqHy.js(~line 375-441): Does not receive or passbashElevatedtorunEmbeddedPiAgentrunEmbeddedPiAgentindist/subagent-registry-kdTa9uwX.js(~line 58200): Passesparams.bashElevatedthrough correctly, but receivesundefinedcreateExecToolindist/subagent-registry-kdTa9uwX.js(~line 11180): Whendefaults.elevatedisundefined,elevatedAllowed=false, gate check always failsAll Affected Callers
Every caller of
callGateway({ method: "agent" })hits this bug:sessions_spawn(line ~26696) — sub-agent task spawnsessions_send(line ~26329, 26352) — cross-session messagingsubagents steer(line ~17111) — steering existing sub-agentsrunAgentStep(line ~25962) — internal agent step executionSuggested Fix
Add
resolveElevatedPermissions()toagentCommand:Alternatively, as defense-in-depth,
createExecToolcould fall back to resolving elevated from the live config whendefaults.elevatedisundefined.Impact
This bug makes elevated access unreliable for any agent using
sandbox.mode: "all"with sub-agents. The parent session's elevated breaks every time a sub-agent attempts and fails elevated, requiring a new channel message to restore it. This blocks automated/overnight workflows where no human is available to send a recovery message.Workaround
Set
sandbox.mode: "non-main"for the affected agent so the main session runs on the host and doesn't need elevated. Sub-agents remain sandboxed.