openclaw - ✅(Solved) Fix [Bug]: exec host=node invoke-failed after approval (APPROVAL_CLIENT_MISMATCH) via Control UI [1 pull requests, 2 comments, 3 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#78569Fetched 2026-05-07 03:35:16
View on GitHub
Comments
2
Participants
3
Timeline
10
Reactions
2
Assignees
Timeline (top)
commented ×2cross-referenced ×2labeled ×2assigned ×1

After upgrading from 2026.4.22 to 2026.5.5, exec host=node commands that require approval (not in allowlist, ask=on-miss) always fail with invoke-failed after user approves via Control UI. Commands matching the allowlist (no approval needed) execute successfully. Gateway log shows: node.invoke errorCode=INVALID_REQUEST errorMessage=approval id not valid for this client.

Root Cause

Root cause in src/gateway/node-invoke-system-run-approval.ts:

  • snapshot.requestedByDeviceId is null (Control UI has no deviceId)
  • snapshot.requestedByConnId (webchat connId) ≠ opts.client.connId (internal gateway connId from callGatewayTool)
  • Code: APPROVAL_CLIENT_MISMATCH

Fix Action

Fix / Workaround

Affected: Any operator using Control UI (token auth) with node-backed exec and approval mode. Severity: High (completely blocks node exec approval workflow). Frequency: 100% reproducible. Consequence: Cannot execute any non-allowlisted command on remote nodes via approval flow. Must use workarounds (add to allowlist or disable approval entirely).

Last known good version: 2026.4.22. First known bad version: 2026.5.5. The APPROVAL_CLIENT_MISMATCH code exists in both versions — the regression is likely in how callGatewayTool("node.invoke") passes client context after approval, not in the guard itself. Workaround: openclaw approvals allowlist add --node <name> "/path/to/bin" (bypasses approval). Possibly related: #77656, #43279.

PR fix notes

PR #78728: Fix Control UI node exec approvals

Description (problem / solution / changelog)

Summary

  • Fix no-device Control UI node exec approvals so approved system.run replays can complete through the trusted backend gateway client.
  • Keep device, node, command, cwd, env, session, expiry, and allow-once replay bindings enforced.
  • Add regression tests for the trusted backend path and blocked replay cases.

Fixes #78569

Real behavior proof

Behavior or issue addressed: #78569 reported that token-auth, no-device Control UI node exec approvals failed after approval because the approved backend node.invoke system.run replay used a different connection and hit APPROVAL_CLIENT_MISMATCH.

Real environment tested: Source gateway on loopback with isolated temp state and token auth; browser-style openclaw-control-ui WebSocket clients connected with a real Origin header, token auth, no device identity, and gateway.controlUi.dangerouslyDisableDeviceAuth=true to match the reported token-only/no-device Control UI setup; paired Linux node client declaring system.run; trusted backend gateway-client with operator.write and operator.approvals.

Exact steps or command run after this patch:

pnpm tsx .artifacts/proof-node-exec-control-ui-approval.mts

Evidence after fix: PR comment with copied live terminal output: https://github.com/openclaw/openclaw/pull/78728#issuecomment-4393809445. The copied output includes PROOF {"scenario":"token-auth no-device Control UI approval -> backend node.invoke -> paired node system.run","gateway":"source gateway, loopback token auth, isolated temp state","node":{"connected":true,"command":"system.run"},"success":{"approvalIdPrefix":"proof-success-2788","stdout":"CONTROL_UI_NODE_APPROVAL_1f35b7a4","exitCode":0},"negativeControl":{"replayClient":"openclaw-control-ui on a different no-device connection","rejected":"approval id not valid for this client"}}.

Observed result after fix: Control UI requested and approved a node exec approval; the trusted backend gateway-client replayed node.invoke system.run with the approved runId and returned stdout CONTROL_UI_NODE_APPROVAL_1f35b7a4 with exit code 0. Negative control: a different no-device Control UI connection replaying directly was rejected with approval id not valid for this client.

What was not tested: Full Docker deployment with an external browser session was not run; the proof used the source gateway and real WebSocket/RPC clients against an isolated local loopback gateway.

Verification

  • pnpm test src/gateway/node-invoke-system-run-approval.test.ts src/agents/bash-tools.exec-host-node.test.ts src/agents/bash-tools.exec.approval-id.test.ts
  • pnpm exec oxfmt --check --threads=1 src/gateway/exec-approval-manager.ts src/gateway/server-methods/exec-approval.ts src/gateway/node-invoke-system-run-approval.ts src/gateway/node-invoke-system-run-approval.test.ts src/agents/bash-tools.exec-host-node.ts src/agents/bash-tools.exec-host-node.test.ts CHANGELOG.md
  • git diff --check

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • src/agents/bash-tools.exec-host-node.test.ts (modified, +2/-0)
  • src/agents/bash-tools.exec-host-node.ts (modified, +23/-17)
  • src/gateway/exec-approval-manager.ts (modified, +1/-0)
  • src/gateway/node-invoke-system-run-approval.test.ts (modified, +120/-1)
  • src/gateway/node-invoke-system-run-approval.ts (modified, +35/-1)
  • src/gateway/server-methods/exec-approval.ts (modified, +1/-0)

Code Example

2026-05-06T15:37:16.324+00:00 info gateway/ws ⇄ res ✗ node.invoke 1ms errorCode=INVALID_REQUEST errorMessage=approval id not valid for this client conn=741709da…e3ce id=ada62db2…2d72

Root cause in src/gateway/node-invoke-system-run-approval.ts:
- snapshot.requestedByDeviceId is null (Control UI has no deviceId)
- snapshot.requestedByConnId (webchat connId) ≠ opts.client.connId (internal gateway connId from callGatewayTool)
- Code: APPROVAL_CLIENT_MISMATCH

Verification:
- Allowlist-matched commands (e.g. /usr/bin/mkdir on lin) execute without approval → works ✅
- Gateway-local exec (host=gateway) with approval → works ✅
- Node exec with approval → always fails ❌
RAW_BUFFERClick to expand / collapse

Bug type

Regression (worked before, now fails)

Beta release blocker

No

Summary

After upgrading from 2026.4.22 to 2026.5.5, exec host=node commands that require approval (not in allowlist, ask=on-miss) always fail with invoke-failed after user approves via Control UI. Commands matching the allowlist (no approval needed) execute successfully. Gateway log shows: node.invoke errorCode=INVALID_REQUEST errorMessage=approval id not valid for this client.

Steps to reproduce

  1. Connect to gateway via Control UI (token auth, not a paired device).
  2. Have a Linux node paired and connected with system.run declared.
  3. Use default exec policy: tools.exec.security=allowlist, tools.exec.ask=on-miss.
  4. Run any command on the node not in the exec allowlist: exec(host=node, node="gw-host", command="echo hello").
  5. Approve via /approve <id> allow-once in the Control UI chat.
  6. Observe: Exec denied (node=... id=..., invoke-failed): echo hello.

Expected behavior

After user approves, the command executes on the node and returns output. This worked in 2026.4.22.

Actual behavior

After approval, gateway internally calls node.invoke but APPROVAL_CLIENT_MISMATCH guard rejects it. Log: "node.invoke 1ms errorCode=INVALID_REQUEST errorMessage=approval id not valid for this client". The approval record's requestedByConnId does not match opts.client.connId used during callGatewayTool("node.invoke"). Since Control UI has no deviceId (token auth, not paired), there is no requestedByDeviceId fallback.

OpenClaw version

2026.5.5

Operating system

Oracle Linux 8.10 (arm64, Docker)

Install method

docker

Model

github-copilot/claude-opus-4.6

Provider / routing chain

openclaw gateway -> paired Linux node (system.run)

Additional provider/model setup details

Gateway runs in Docker container (openclaw-openclaw-gateway-1). Two Linux nodes: gw-host (v2026.5.5) and naturedog-ubuntu (v2026.5.5). Client is Control UI via token auth — not a paired device, so no deviceId is bound. Node exec-approvals defaults: security=full, ask=off. Gateway tools.exec defaults: security=allowlist, ask=on-miss. Effective policy for main agent: security=allowlist, ask=on-miss.

Logs, screenshots, and evidence

2026-05-06T15:37:16.324+00:00 info gateway/ws ⇄ res ✗ node.invoke 1ms errorCode=INVALID_REQUEST errorMessage=approval id not valid for this client conn=741709da…e3ce id=ada62db2…2d72

Root cause in src/gateway/node-invoke-system-run-approval.ts:
- snapshot.requestedByDeviceId is null (Control UI has no deviceId)
- snapshot.requestedByConnId (webchat connId) ≠ opts.client.connId (internal gateway connId from callGatewayTool)
- Code: APPROVAL_CLIENT_MISMATCH

Verification:
- Allowlist-matched commands (e.g. /usr/bin/mkdir on lin) execute without approval → works ✅
- Gateway-local exec (host=gateway) with approval → works ✅
- Node exec with approval → always fails ❌

Impact and severity

Affected: Any operator using Control UI (token auth) with node-backed exec and approval mode. Severity: High (completely blocks node exec approval workflow). Frequency: 100% reproducible. Consequence: Cannot execute any non-allowlisted command on remote nodes via approval flow. Must use workarounds (add to allowlist or disable approval entirely).

Additional information

Last known good version: 2026.4.22. First known bad version: 2026.5.5. The APPROVAL_CLIENT_MISMATCH code exists in both versions — the regression is likely in how callGatewayTool("node.invoke") passes client context after approval, not in the guard itself. Workaround: openclaw approvals allowlist add --node <name> "/path/to/bin" (bypasses approval). Possibly related: #77656, #43279.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

After user approves, the command executes on the node and returns output. This worked in 2026.4.22.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix [Bug]: exec host=node invoke-failed after approval (APPROVAL_CLIENT_MISMATCH) via Control UI [1 pull requests, 2 comments, 3 participants]