openclaw - 💡(How to fix) Fix TUI cannot connect: device identity required but TUI has no localStorage [1 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#57453Fetched 2026-04-08 01:49:28
View on GitHub
Comments
0
Participants
1
Timeline
0
Reactions
0
Author
Participants

Error Message

gateway connect failed: GatewayClientRequestError: control ui requires device identity (use HTTPS or localhost secure context)

Root Cause

TUI is classified as isOperatorUiClient (same as browser Control UI) in message-channel-BaBrchOc.js:

function isOperatorUiClient(client) {
    return clientId === GATEWAY_CLIENT_NAMES.CONTROL_UI || clientId === GATEWAY_CLIENT_NAMES.TUI;
}

This means TUI goes through the Control UI device identity authentication flow, which requires generating and storing an Ed25519 keypair. However, the device identity implementation relies on browser localStorage to persist the keypair:

var Xt = "openclaw-device-identity-v1";
// ...
e?.setItem(Xt, JSON.stringify(n))  // uses localStorage

Since TUI is a terminal/Node.js application, it has no localStorage, so it can never provide a device identity — causing the connection to be rejected every time.

Fix Action

Fix / Workaround

Current Workaround

Code Example

gateway connect failed: GatewayClientRequestError: control ui requires device identity (use HTTPS or localhost secure context)

---

function isOperatorUiClient(client) {
    return clientId === GATEWAY_CLIENT_NAMES.CONTROL_UI || clientId === GATEWAY_CLIENT_NAMES.TUI;
}

---

var Xt = "openclaw-device-identity-v1";
// ...
e?.setItem(Xt, JSON.stringify(n))  // uses localStorage
RAW_BUFFERClick to expand / collapse

Bug Description

After upgrading to OpenClaw 2026.3.28 (f9b1079), running openclaw tui on the same machine as the gateway fails with:

gateway connect failed: GatewayClientRequestError: control ui requires device identity (use HTTPS or localhost secure context)

Root Cause

TUI is classified as isOperatorUiClient (same as browser Control UI) in message-channel-BaBrchOc.js:

function isOperatorUiClient(client) {
    return clientId === GATEWAY_CLIENT_NAMES.CONTROL_UI || clientId === GATEWAY_CLIENT_NAMES.TUI;
}

This means TUI goes through the Control UI device identity authentication flow, which requires generating and storing an Ed25519 keypair. However, the device identity implementation relies on browser localStorage to persist the keypair:

var Xt = "openclaw-device-identity-v1";
// ...
e?.setItem(Xt, JSON.stringify(n))  // uses localStorage

Since TUI is a terminal/Node.js application, it has no localStorage, so it can never provide a device identity — causing the connection to be rejected every time.

Steps to Reproduce

  1. Install OpenClaw 2026.3.28
  2. Start the gateway: openclaw-gateway (default loopback bind)
  3. Run openclaw tui on the same machine
  4. Connection fails with the error above

Current Workaround

Setting gateway.controlUi.dangerouslyDisableDeviceAuth: true in openclaw.json bypasses the device identity check. This is safe when the gateway binds to loopback with token auth, but:

  • The "dangerously" naming is alarming for users
  • It should not be required for a local TUI connection

Suggested Fix

  1. Give TUI a file-based keystore (e.g. ~/.openclaw/device-identity.json) instead of relying on localStorage
  2. Or exempt TUI from the browser device identity flow and use a separate auth path (TUI already provides the gateway token)
  3. Or at minimum, detect that the client is TUI + local + token-authenticated and auto-allow without device identity

Environment

  • OpenClaw: 2026.3.28 (f9b1079)
  • Node.js: v22.22.0
  • OS: OpenCloudOS 9 (Linux)
  • Gateway bind: loopback
  • Auth mode: token

extent analysis

Fix Plan

To resolve the issue, we will implement a file-based keystore for TUI. Here are the steps:

  • Create a new file device-identity.json in the ~/.openclaw directory to store the Ed25519 keypair.
  • Modify the message-channel-BaBrchOc.js file to use the file-based keystore for TUI.

Example code:

const fs = require('fs');
const path = require('path');

const deviceIdentityFile = path.join(os.homedir(), '.openclaw', 'device-identity.json');

function getDeviceIdentity() {
  try {
    const data = fs.readFileSync(deviceIdentityFile, 'utf8');
    return JSON.parse(data);
  } catch (err) {
    // Generate a new keypair and save it to the file
    const keypair = generateEd25519Keypair();
    fs.writeFileSync(deviceIdentityFile, JSON.stringify(keypair));
    return keypair;
  }
}

function generateEd25519Keypair() {
  // Implement Ed25519 keypair generation
  // ...
}
  • Update the isOperatorUiClient function to use the file-based keystore for TUI:
function isOperatorUiClient(client) {
  if (client === GATEWAY_CLIENT_NAMES.TUI) {
    return getDeviceIdentity();
  }
  // ...
}

Verification

To verify that the fix worked, run the following steps:

  • Start the gateway: openclaw-gateway (default loopback bind)
  • Run openclaw tui on the same machine
  • Check that the connection is established successfully

Extra Tips

  • Make sure to handle errors and exceptions properly when reading and writing to the file-based keystore.
  • Consider implementing additional security measures, such as encrypting the keypair stored in the file.

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…

Still need to ship something?

×6

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

Back to top recommendations

TRENDING