#@krill

1 messages · Page 1 of 1 (latest)

neon estuary
#

@summer falcon

Issue: sessions_spawn tool fails with error: gateway closed (1008): pairing required

Context:

• Running OpenClaw gateway locally
• Telegram channel configured with dmPolicy: pairing (correct - only owner can DM)
• Cron jobs work fine (they use sessionTarget: isolated)
• CLI command openclaw agent --agent researcher works
• But using the sessions_spawn tool from main session fails

What I've tried:

• Restarting gateway
• Checking config (dmPolicy is "pairing")
• Verifying cron jobs work (they do)
• Testing CLI workaround (works)

The error happens when:

sessions_spawn(label="test", task="Say hi")
→ fails with: "gateway closed (1008): pairing required"

Version feb 19

Question: Is this expected behavior? Is there a way to fix it, or should we use cron jobs for all background tasks instead?

oblique wolfBOT
#

To help others find answers, you can mark your question as solved via Right click solution message -> Apps -> âś… Mark Solution

neon estuary
#

@summer falcon

summer falconBOT
#

Not expected behavior — sessions_spawn shouldn’t require you to “use cron for everything”.

That specific error (gateway closed (1008): pairing required) is Gateway device pairing, not Telegram dmPolicy: pairing.

Most likely cause

When sessions_spawn starts a sub-agent, something in that path is connecting back to the Gateway WS as a device (often from a sandbox/container/network that’s not treated as loopback), and the Gateway is refusing it until it’s approved.

Fix: approve the pending device request

  1. Trigger it once (so it generates a pending request), then immediately run:
openclaw devices list
  1. If you see a pending request, approve it:
#
openclaw devices approve <requestId>
  1. Retry sessions_spawn.

Docs: https://docs.openclaw.ai/web/control-ui#device-pairing-first-connection
(yes, same mechanism)

What I need from you to be sure (quick)

Please paste:

openclaw --version
openclaw devices list

And paste the full sessions_spawn error text (the one that includes lines like Gateway target: ... and Source: ...). The Source: line is the giveaway (loopback vs LAN vs docker bridge like 172.18.x.x).

#

If you’re on a Feb 19 build

There are active bug reports around 2026.2.19-2 causing “pairing required” in places it shouldn’t (CLI/subagents). If your openclaw --version shows that exact build and no pending device ever appears, it’s likely that regression — best next step is to update to the latest (or roll back to the last-known-good) and/or add your details to a GitHub issue:
https://github.com/openclaw/openclaw/issues

If the device-approve step fixes it, please mark the solution (right-click the solution message → Apps → ✅ Mark Solution) so Answer Overflow indexes it.

neon estuary
#

freeman@DESKTOP-P1FF11M:~$ openclaw --version
2026.2.19-2
freeman@DESKTOP-P1FF11M:~$ openclaw devices list

🦞 OpenClaw 2026.2.19-2 (45d9b20) — I can run local, remote, or purely on vibes—results may vary with DNS.

│
gateway connect failed: Error: unauthorized: device token mismatch (rotate/reissue device token)
â—‡
[openclaw] Failed to start CLI: Error: gateway closed (1008): unauthorized: device token mismatch (rotate/reissue device token)
Gateway target: ws://127.0.0.1:18789
Source: local loopback
Config: /home/freeman/.openclaw/openclaw.json
Bind: loopback
at Object.onClose (file:///home/freeman/.npm-global/lib/node_modules/openclaw/dist/call-DZzTR0NL.js:438:10)
at WebSocket.<anonymous> (file:///home/freeman/.npm-global/lib/node_modules/openclaw/dist/client-DoSZFvf3.js:1538:23)
at WebSocket.emit (node:events:519:28)
at WebSocket.emitClose (/home/freeman/.npm-global/lib/node_modules/openclaw/node_modules/ws/lib/websocket.js:273:10)
at Socket.socketOnClose (/home/freeman/.npm-global/lib/node_modules/openclaw/node_modules/ws/lib/websocket.js:1346:15)
at Socket.emit (node:events:519:28)
at TCP.<anonymous> (node:net:346:12)
freeman@DESKTOP-P1FF11M:~$

neon estuary
# summer falcon ## If you’re on a Feb 19 build There are active bug reports around **2026.2.19-2...

freeman@DESKTOP-P1FF11M:~$ openclaw --version
2026.2.19-2
freeman@DESKTOP-P1FF11M:~$ openclaw devices list

OpenClaw 2026.2.19-2 (45d9b20) — I can run local, remote, or purely on vibes—results may vary with DNS.

│
gateway connect failed: Error: unauthorized: device token mismatch (rotate/reissue device token)
â—‡
[openclaw] Failed to start CLI: Error: gateway closed (1008): unauthorized: device token mismatch (rotate/reissue device token)
Gateway target: ws://127.0.0.1:18789
Source: local loopback
Config: /home/freeman/.openclaw/openclaw.json
Bind: loopback
at Object.onClose (file:///home/freeman/.npm-global/lib/node_modules/openclaw/dist/call-DZzTR0NL.js:438:10)
at WebSocket.<anonymous> (file:///home/freeman/.npm-global/lib/node_modules/openclaw/dist/client-DoSZFvf3.js:1538:23)
at WebSocket.emit (node:events:519:28)
at WebSocket.emitClose (/home/freeman/.npm-global/lib/node_modules/openclaw/node_modules/ws/lib/websocket.js:273:10)
at Socket.socketOnClose (/home/freeman/.npm-global/lib/node_modules/openclaw/node_modules/ws/lib/websocket.js:1346:15)
at Socket.emit (node:events:519:28)
at TCP.<anonymous> (node:net:346:12)
freeman@DESKTOP-P1FF11M:~$

summer falconBOT
#

Yep — that output is the other (more fatal) variant of this problem:

  • You’re on 2026.2.19-2
  • The Gateway is up on loopback
  • But the CLI can’t even do devices list because the CLI’s cached “device auth token” no longer matches what the Gateway has in devices/paired.json → unauthorized: device token mismatch

That breaks everything that needs a CLI↔gateway WS connection, including sessions_spawn.

Quick workaround (no gateway access needed)

This is all local files. Don’t paste tokens into Discord.

  1. Back up the CLI auth file:
cp ~/.openclaw/identity/device-auth.json ~/.openclaw/identity/device-auth.json.bak 2>/dev/null || true
  1. Try the simplest fix first: delete the stale token file (it should be re-issued on next connect):
#
rm -f ~/.openclaw/identity/device-auth.json
  1. Now try:
openclaw status

(or openclaw devices list)

If it works, you’re done.

If it still fails: manually “sync” the token

What’s mismatching is typically:

  • CLI token: ~/.openclaw/identity/device-auth.json
  • Gateway truth: ~/.openclaw/devices/paired.json
#
  • Device id: ~/.openclaw/identity/device.json

You can check your device id with:

jq -r .deviceId ~/.openclaw/identity/device.json

Then (locally) open ~/.openclaw/devices/paired.json, find that deviceId entry, and copy the operator token into ~/.openclaw/identity/device-auth.json under the operator role.

(If you want, paste redacted shapes of those JSON files and I’ll tell you the exact jq path—but please do not include the token value.)

Long-term fix

This is a known upgrade regression around 2026.2.19-2. Best fix is to update once a build ships that repairs device-token syncing, but the steps above unblock you immediately.

If the “delete device-auth.json” fix works, please mark the solution (right-click message → Apps → ✅ Mark Solution) so Answer Overflow indexes it.

neon estuary
#

Update for Krill:

Tried the fixes:

  1. Deleted ~/.openclaw/identity/device-auth.json - recreated automatically
  2. Checked device IDs - they match between CLI and Gateway
  3. Restarted gateway
  4. Still getting same error: "gateway closed (1008): pairing required"

CLI version: 2026.2.19-2

Error shows:

• Gateway target: ws://127.0.0.1:18789
• Source: local loopback
• Bind: loopback

Still broken. What's next?

Which version should I regress to and how do I do it without losing anything or breaking anything?

neon estuary
# summer falcon Yep — that output is the *other* (more fatal) variant of this problem: - You’re...

Update for Krill:

Tried the fixes:

  1. Deleted ~/.openclaw/identity/device-auth.json - recreated automatically
  2. Checked device IDs - they match between CLI and Gateway
  3. Restarted gateway
  4. Still getting same error: "gateway closed (1008): pairing required"

CLI version: 2026.2.19-2

Error shows:

• Gateway target: ws://127.0.0.1:18789
• Source: local loopback
• Bind: loopback

Still broken. What's next?

Which version should I regress to and how do I do it without losing anything or breaking anything?

summer falconBOT
#

You’re squarely in a known-bad pocket: 2026.2.19-2 has multiple reports where the Gateway starts rejecting local WS clients (CLI + subagents) with pairing required / device token mismatch, even on 127.0.0.1 loopback. So at this point, regressing is the right move.

What to regress to

Based on the bug reports, 2026.2.17 is a common “last known good” (people report it worked, then broke on 2026.2.19-2).

Related issues (for reference / to add your logs):

How to regress safely (no data loss)

Your data lives in ~/.openclaw/ (config, sessions, pairing/devices, etc). Changing the npm package version won’t wipe it — but do a backup first because downgrades can hit state-format edge cases.

0) Backup state (recommended)

tar -czf ~/openclaw-backup-$(date +%Y%m%d-%H%M%S).tgz ~/.openclaw
#

1) Stop the gateway

If you installed the service:

openclaw gateway stop

(or just stop whatever terminal/process is running it)

2) Downgrade the CLI/gateway code

If you installed via npm global:

npm i -g openclaw@2026.2.17

Verify:

openclaw --version
#

3) Start the gateway again

openclaw gateway start
# or
openclaw gateway restart

4) Retry sessions_spawn

At that point sessions_spawn should stop tripping the gateway WS auth path.

If it’s still “pairing required” after downgrade

Reply with the output of:

openclaw --version
openclaw gateway status

(Those two are safe to paste; they don’t contain secrets.)

#

And if this does fix it: please right-click the solution message → Apps → ✅ Mark Solution so Answer Overflow indexes it.

neon estuary
summer falconBOT
#

What’s biting you isn’t “normal update pain”, it’s basically two classes of problems that show up during fast-moving pre‑1.0 releases:

1) Device token mismatch / “pairing required” after updating

OpenClaw has gateway-client device auth (for the CLI, Control UI, subagents, etc.) that’s separate from Telegram dmPolicy: pairing.

Mechanically, there are two pieces of state that must stay in sync:

  • Gateway’s paired devices + tokens: ~/.openclaw/devices/paired.json
  • CLI’s cached token for its device identity: ~/.openclaw/identity/device-auth.json

Some versions (including the Feb 13-ish window and definitely 2026.2.19-2) have regressions where an update / re-pair ends up rotating the gateway-side token but the CLI side doesn’t properly converge, so you get:

  • unauthorized: device token mismatch or
  • ... (1008): pairing required
    even on ws://127.0.0.1:18789 loopback.

So: it’s not your Telegram config, and it’s not “expected behavior” — it’s a buggy auth-state transition.

#

2) “message ordering conflicts” during/after updating

Almost always this happens when two gateway processes (or two channel workers) end up touching the same channel/session state:

  • service gateway still running + you start another openclaw gateway manually
  • old service entrypoint still points to an older install, so after upgrade you effectively have “split brain”
  • (WSL especially) you think you restarted, but the systemd user service is still running

That produces weird symptoms: out-of-order events, duplicate processing, or channel-specific ordering warnings.

How to update without getting stuck (the reliable routine)

  1. Stop everything (make sure only one gateway exists):
openclaw gateway stop
openclaw gateway status

If status still says “running”, you’ve got a second instance somewhere (service vs foreground).

#
  1. Backup state (so rollback is zero-stress):
tar -czf ~/openclaw-backup-$(date +%Y%m%d-%H%M%S).tgz ~/.openclaw
  1. Upgrade (or pin) via npm, then immediately:
openclaw doctor
openclaw gateway restart
openclaw health

Docs (good checklist): https://docs.openclaw.ai/install/updating

What I’d do in your situation

  • Stay pinned on your known-good Feb 9 build for now.
  • Don’t “walk forward” through the broken builds one by one.
#
  • Wait until the issue threads confirm a fixed build, then try a single jump upgrade using the routine above (with the backup ready).

If you tell me:

  • which channel logged the “message ordering conflicts” (Telegram? WhatsApp?),
  • and whether you run the gateway as a systemd user service in WSL,

…I can give you the exact “single gateway instance” verification commands for that setup (no token pasting needed).

neon estuary
# summer falcon What’s biting you isn’t “normal update pain”, it’s basically two classes of prob...

Here is what openclaw told me we did to fix the problems that popped up i installed feb 19 version: I also seem to recall that if i tried to put the session files from the previous install in to the new version it causes issues, I think tha tmay have been the message ordering conflict?

Summary of Issues Fixed
Issue 1: Gateway Token Mismatch
Problem: After fresh install + restore, CLI couldn't connect to gateway.

Causes:

openclaw.json had old gateway token from backup
Systemd service (~/.config/systemd/user/openclaw-gateway.service) had old token hardcoded
Fix:

Updated openclaw.json gateway token to the new one (7c349eced5d0bfc69c790a95bdf547a36b05bae4fbf7c78e)
Updated systemd service token: sed -i 's/OPENCLAW_GATEWAY_TOKEN=.*/OPENCLAW_GATEWAY_TOKEN=7c349eced5d0bfc69c790a95bdf547a36b05bae4fbf7c78e/' ~/.config/systemd/user/openclaw-gateway.service
Run systemctl --user daemon-reload && openclaw gateway restart
Issue 2: CLI Device Pairing/Approval
Problem: Gateway required scope upgrade approval for CLI.

Fix:

Check ~/.openclaw/devices/pending.json for pending approvals
Approve device by adding to ~/.openclaw/devices/paired.json with required scopes
Clear pending.json
Restart gateway
For Future Updates:
Never restore openclaw.json fully — extract only the sections you need (browser, channels, agents, models) and keep the fresh install's gateway/auth sections
Always update systemd service if you change gateway token
Device approvals may need manual intervention if devices don't auto-pair

summer falconBOT
#

You’ve basically reverse‑engineered the two failure modes correctly — but the root cause isn’t “sessions files”, it’s state + service metadata getting out of sync during reinstall/upgrade, plus a real regression in some Feb builds.

First: rotate that gateway token (you pasted it in Discord)

That value is effectively an admin password for your gateway. Rotate it now:

openclaw config set gateway.auth.token "$(openssl rand -hex 32)" --strict-json
openclaw gateway restart

(Also make sure you don’t have OPENCLAW_GATEWAY_TOKEN=... hardcoded in the systemd unit anymore, or it’ll keep overriding.)

What actually causes the update problems?

A) “Gateway token mismatch”

This happens when there are two sources of truth for the gateway token:

#
  • ~/.openclaw/openclaw.json has gateway.auth.token
  • your systemd user unit exports OPENCLAW_GATEWAY_TOKEN=... (or otherwise embeds the old token)

After an update/reinstall/restore, those can diverge. Then:

  • the gateway service starts with token A
  • the CLI/control-ui tries token B
    → auth failures / pairing loops / “unauthorized”.

Avoidance: after updating, don’t hand-edit systemd units. Instead:

openclaw doctor
openclaw gateway install --force
openclaw gateway restart

That’s the “make the service match this install + this config” button.

B) “Device token mismatch / pairing required” (CLI/subagents)

#

That’s device pairing, unrelated to Telegram DM pairing.

The gateway tracks paired devices in:

  • ~/.openclaw/devices/paired.json

The CLI caches its device identity + token in:

  • ~/.openclaw/identity/device.json
  • ~/.openclaw/identity/device-auth.json

Some versions (notably 2026.2.19-2) have a regression where updates/repairs can get into a loop where the gateway expects a different device token than the CLI has cached.

Avoidance: once you’re on a good build, you should never need to edit paired.json by hand. Use:

openclaw devices list
openclaw devices approve <requestId>
openclaw devices rotate --device <id> --role operator --scope operator.read --scope operator.write
#

C) “Message ordering conflicts”

This is usually one of these:

  • two gateways running at once (foreground + systemd service), both reading/writing the same state
  • restoring partial state (e.g., copying sessions/transcripts but not the related indices/metadata), causing replay/out-of-order effects

So your hunch about “copying session files” isn’t crazy, but the more common culprit is duplicate gateway processes.

The safest way to update going forward

If you want “don’t brick my working setup”:

  1. Always backup:
tar -czf ~/openclaw-backup-$(date +%Y%m%d-%H%M%S).tgz ~/.openclaw
  1. Update in-place (don’t fresh install + restore unless you have to)
#
  1. Immediately run:
openclaw doctor
openclaw gateway install --force
openclaw gateway restart
openclaw health

Docs: https://docs.openclaw.ai/install/updating

What I’d do right now

Given you’ve hit this multiple times: stay pinned to your known-good Feb 9 build until the device-token regression is confirmed fixed, then jump forward once using the routine above.

If you paste (no secrets) the output of:

openclaw gateway status
#

I can tell you if you’re in the “unit file overrides config” situation and exactly what to remove.

neon estuary
# summer falcon I can tell you if you’re in the “unit file overrides config” situation and exact...

opefreeman@DESKTOP-P1FF11M:~$ openclaw gateway status

🦞 OpenClaw 2026.2.19-2 (45d9b20) — I can grep it, git blame it, and gently roast it—pick your coping mechanism.

│
â—‡
Service: systemd (enabled)
File logs: /tmp/openclaw/openclaw-2026-02-22.log
Command: /usr/bin/node /home/freeman/.npm-global/lib/node_modules/openclaw/dist/index.js gateway --port 18789
Service file: ~/.config/systemd/user/openclaw-gateway.service
Service env: OPENCLAW_GATEWAY_PORT=18789

Config (cli): ~/.openclaw/openclaw.json
Config (service): ~/.openclaw/openclaw.json

Gateway: bind=loopback (127.0.0.1), port=18789 (service args)
Probe target: ws://127.0.0.1:18789
Dashboard: http://127.0.0.1:18789/
Probe note: Loopback-only gateway; only local clients can connect.

Runtime: running (pid 1093880, state active, sub running, last exit 0, reason 0)
RPC probe: ok

Listening: 127.0.0.1:18789
Other gateway-like services detected (best effort):

  • auto_summarize.service (user, unit: /home/freeman/.config/systemd/user/auto_summarize.service)
  • token_logger.service (user, unit: /home/freeman/.config/systemd/user/token_logger.service)
    Cleanup hint: systemctl --user disable --now openclaw-gateway.service
    Cleanup hint: rm ~/.config/systemd/user/openclaw-gateway.service

Recommendation: run a single gateway per machine for most setups. One gateway supports multiple agents (see docs: /gateway#multiple-gateways-same-host).
If you need multiple gateways (e.g., a rescue bot on the same host), isolate ports + config/state (see docs: /gateway#multiple-gateways-same-host).

Troubles: run openclaw status

summer falconBOT
#

Your gateway status output is actually good news: you’re not in the “systemd unit is overriding the token” situation anymore.

  • Config (cli) == Config (service) (same ~/.openclaw/openclaw.json)
  • Service env only sets port (no OPENCLAW_GATEWAY_TOKEN shown)
  • RPC probe: ok (so the CLI can talk to the gateway at least for gateway status)

So the remaining breakage you’re seeing on 2026.2.19-2 is almost certainly device auth / scope-upgrade + a regression in that build, not a config-vs-service mismatch.

What’s causing these problems during updates?

1) Device auth + scope upgrades changed between versions

Newer builds sometimes introduce/require new operator scopes (e.g. operator.write). When a client (CLI / subagent runner / control UI) doesn’t have them yet, the gateway will force a pairing/repair flow → shows up as ... (1008): pairing required.

Normally you’d see a pending device request and approve it via:

openclaw devices list
openclaw devices approve <requestId>
#

2) “Message ordering conflicts” are usually “two gateways” (or duplicate channel workers)

That tends to happen when:

  • a systemd service is running and you start another openclaw gateway manually, or
  • you have multiple installs/profiles accidentally pointing at the same state dir.

Copying “session files” around can make things weird, but the #1 cause I’ve seen is two processes touching the same channel/session state.

What to do next (safe + deterministic)

A) See if there’s a pending device scope upgrade when sessions_spawn fails

  1. Trigger the failure (run the thing that causes sessions_spawn)
  2. Immediately run:
openclaw devices list --json

If you see a pending request marked as a repair/scope upgrade, approve it with openclaw devices approve ….

B) If you just want a working system: pin back to your known-good Feb 9 version

#

That’s the least risky path right now. Pinning the npm package does not delete ~/.openclaw.

  1. Backup:
tar -czf ~/openclaw-backup-$(date +%Y%m%d-%H%M%S).tgz ~/.openclaw
  1. Install the exact version that worked (whatever openclaw --version was back then):
npm i -g openclaw@<that_version>
openclaw doctor
openclaw gateway restart

Best practice so you can “try updates without risking your working bot”

Use a separate profile (separate state dir + port) for testing new versions. That way you can break the test profile and your main one stays fine:

  • openclaw --profile test ... (creates ~/.openclaw-test)
#

If you want, tell me what your Feb 9 openclaw --version string was (or paste npm view openclaw versions --json | tail -n 20) and I’ll tell you exactly what to pin to + a clean “test profile” command sequence.

neon estuary
# summer falcon If you want, tell me what your Feb 9 `openclaw --version` string was (or paste `...

Here is whay my openclaw agent says:

Here's exactly what was done:

───

Problem: Sub-agents failing with "gateway closed (1008): pairing required" - the device token regression in v2026.2.19-2

Fix steps:

  1. Rotated gateway token:

openclaw config set gateway.auth.token "$(openssl rand -hex 32)"

  1. Synced systemd service with new config:

openclaw gateway install --force

  1. Checked device status:

openclaw devices list

Found 1 pending repair request (69774ce4-7b8e-45d4-8f05-fceb28860510)

  1. Approved the device repair:

openclaw devices approve 69774ce4-7b8e-45d4-8f05-fceb28860510

  1. Tested sub-agent spawn - worked! âś…

───

Result: Gateway running, all sub-agents working, security token rotated.

Note: Still on v2026.2.19-2 (has the regression). Krill suggested pinning to Feb 9 build until regression is fixed.

THEN I SAID:

wait what? I have this error when I run TUI:

pefreeman@DESKTOP-P1FF11M:~$ openclaw tui

🦞 OpenClaw 2026.2.19-2 (45d9b20) — End-to-end encrypted, drama-to-drama excluded.

openclaw tui - ws://127.0.0.1:18789 - agent main - session main
connecting | idle
gateway disconnected: unauthorized: device token mismatch (rotate/reissue device token) | idle ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
gateway connect failed: Error: unauthorized: device token mismatch (rotate/reissue device token)
gateway connect failed: Error: unauthorized: device token mismatch (rotate/reissue device token)────────────────────────
gateway connect failed: Error: unauthorized: device token

summer falconBOT
#

That pattern makes sense: sub-agents work after you approved the pending repair request, but TUI still fails with:

unauthorized: device token mismatch (rotate/reissue device token)

That usually means the gateway rotated/updated the device’s operator token in:

  • ~/.openclaw/devices/paired.json

…but your local client cache didn’t get updated in:

  • ~/.openclaw/identity/device-auth.json

On 2026.2.19-2 there are reports of exactly this “approved/rotated but the local device-auth.json doesn’t converge” behavior.

Fix (local sync, no token pasting)

Run this on the same Linux user that runs the systemd user gateway (looks like freeman):

#
python3 - <<'PY'
import json, os, time, pathlib

state = os.path.expanduser("~/.openclaw")
device_path = os.path.join(state, "identity", "device.json")
paired_path = os.path.join(state, "devices", "paired.json")
auth_path   = os.path.join(state, "identity", "device-auth.json")

device = json.load(open(device_path))
device_id = device["deviceId"]

paired = json.load(open(paired_path))
if device_id not in paired:
    raise SystemExit(f"Device {device_id} not found in paired.json (wrong user/state dir, or not approved).")
#
op = paired[device_id]["tokens"].get("operator")
if not op or "token" not in op:
    raise SystemExit("No operator token found for this device in paired.json.")

try:
    existing = json.load(open(auth_path))
except FileNotFoundError:
    existing = {"version": 1, "deviceId": device_id, "tokens": {}}

existing["version"] = 1
existing["deviceId"] = device_id
existing.setdefault("tokens", {})
existing["tokens"]["operator"] = {
    "token": op["token"],
    "role": "operator",
#
    "scopes": op.get("scopes", []),
    "updatedAtMs": int(time.time() * 1000),
}

pathlib.Path(os.path.dirname(auth_path)).mkdir(parents=True, exist_ok=True)
tmp = auth_path + ".tmp"
with open(tmp, "w") as f:
    json.dump(existing, f, indent=2)
    f.write("\n")
os.replace(tmp, auth_path)
os.chmod(auth_path, 0o600)

print("Synced ~/.openclaw/identity/device-auth.json from ~/.openclaw/devices/paired.json")
PY
#

Then retry:

openclaw tui

If that script errors with “Device … not found in paired.json”

That means the TUI is running under a different user / different state dir than the gateway approval you did.

Quick sanity checks:

whoami
echo $HOME
ls -la ~/.openclaw/identity/device.json
#

(Your gateway service is clearly using /home/freeman/.openclaw/... from earlier output.)

Why subagents worked but TUI didn’t

Subagents can succeed once the gateway can do its internal work, but TUI is a WS client that must pass the device token check every time. If the local cache is stale, TUI gets bounced even though the gateway is otherwise healthy.

If this fixes it, please mark the solution (right-click → Apps → ✅ Mark Solution) so it’s searchable later.

neon estuary
summer falconBOT
#

If the sync script “ran correctly” but openclaw tui still says device token mismatch, we need to figure out which of these is true:

  1. TUI is reading a different state dir than the gateway (or than the script wrote to)
  2. The deviceId matches but the operator token in device-auth.json still differs from devices/paired.json
  3. Tokens match on disk, but the gateway is actually using a different paired.json at runtime (service env / profile mismatch)

To pin that down, please run exactly these and paste the output. They’re designed to avoid leaking secrets.

1) Confirm user + state dir (safe)

whoami
echo "$HOME"
echo "${OPENCLAW_STATE_DIR:-<not set>}"
ls -ld ~/.openclaw ~/.openclaw-* 2>/dev/null || true

2) Compare token hashes (safe – no raw tokens)

#

This prints deviceId + sha256 hashes of the operator token from both files.

D="${OPENCLAW_STATE_DIR:-$HOME/.openclaw}"

DEVICE_ID="$(jq -r .deviceId "$D/identity/device.json")"

AUTH_HASH="$(jq -r '.tokens.operator.token' "$D/identity/device-auth.json" | sha256sum | cut -d' ' -f1)"
PAIRED_HASH="$(jq -r --arg id "$DEVICE_ID" '.[$id].tokens.operator.token' "$D/devices/paired.json" | sha256sum | cut -d' ' -f1)"

echo "deviceId=$DEVICE_ID"
echo "authHash=$AUTH_HASH"
echo "pairedHash=$PAIRED_HASH"

What I’m looking for:

  • If authHash != pairedHash → your local cache is still not synced (or immediately being rewritten back to the wrong value).
#
  • If authHash == pairedHash and TUI still fails → the gateway service is likely reading a different state dir than you think.

3) Grab the gateway log lines around the failure (safe)

Run openclaw tui in one terminal until it errors, then in another:

tail -n 200 /tmp/openclaw/openclaw-*.log | grep -iE "device token mismatch|pairing required|device|operator" | tail -n 80

Those log lines usually include the deviceId and whether it’s a token mismatch vs scope mismatch vs “not paired”.

4) Check systemd service env (redact if it contains secrets)

This should not contain tokens; but paste it anyway (and redact if it does):

systemctl --user show openclaw-gateway.service -p Environment
#
systemctl --user show openclaw-gateway.service -p ExecStart

Once you paste outputs for (1) + (2) + (3), I can tell you the exact next step (and whether this is fixable locally vs “just downgrade off 2026.2.19-2”).

neon estuary
neon estuary
# summer falcon ```bash systemctl --user show openclaw-gateway.service -p ExecStart ``` Once yo...

$ tail -n 200 /tmp/openclaw/openclaw-*.log | grep -iE "device token mismatch|pairing required|device|operator" | tail -n 80
{"0":"{"subsystem":"gateway"}","1":"security audit: device access upgrade requested reason=scope-upgrade device=ad7522285f008d32b4a866caa124eb48a0e4ddeba5ce5a7ed076af11cdc5d767 ip=unknown-ip auth=token roleFrom=operator roleTo=operator scopesFrom=operator.admin,operator.approvals,operator.pairing,operator.read scopesTo=operator.write client=gateway-client conn=8b254eba-d0d4-463b-bc81-2dd6debe3307","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{"subsystem":"gateway"}","parentNames":["openclaw"],"date":"2026-02-22T08:28:39.706Z","logLevelId":4,"logLevelName":"WARN","path":{"fullFilePath":"file:///home/freeman/.npm-global/lib/node_modules/openclaw/dist/subsystem-BCQGGxdd.js:438:14","fileName":"subsystem-BCQGGxdd.js","fileNameWithLine":"subsystem-BCQGGxdd.js:438","fileColumn":"14","fileLine":"438","filePath":".npm-global/lib/node_modules/openclaw/dist/subsystem-BCQGGxdd.js","filePathWithLine":".npm-global/lib/node_modules/openclaw/dist/subsystem-BCQGGxdd.js:438","method":"logToFile"}},"time":"2026-02-22T08:28:39.706Z"}
{"0":"{"subsystem":"gateway/ws"}","1":{"cause":"pairing-required","handshake":"failed","durationMs":32,"lastFrameType":"req","lastFrameMethod":"connect","lastFrameId":"db564d41-bc9b-4780-afc0-d128ee355f78","host":"127.0.0.1:18789","deviceId":"ad7522285f008d32b4a866caa124eb48a0e4ddeba5ce5a7ed076af11cdc5d767","requestId":"01d20275-246f-4915-985d-229a7db7bdfd","reason":"scope-upgrade"},"2":"closed before connect conn=8b254eba-d0d4-463b-bc81-2dd6debe3307 remote=127.0.0.1 fwd=n/a origin=n/a host=127.0.0.1:18789 ua=n/a code=1008 reason=pairing required","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{"subsystem":"gateway/ws"}","parentNames":["openclaw"],"date":"2026-

neon estuary
# summer falcon ```bash systemctl --user show openclaw-gateway.service -p ExecStart ``` Once yo...

02-22T08:28:39.735Z","logLevelId":4,"logLevelName":"WARN","path":{"fullFilePath":"file:///home/freeman/.npm-global/lib/node_modules/openclaw/dist/subsystem-BCQGGxdd.js:437:51","fileName":"subsystem-BCQGGxdd.js","fileNameWithLine":"subsystem-BCQGGxdd.js:437","fileColumn":"51","fileLine":"437","filePath":".npm-global/lib/node_modules/openclaw/dist/subsystem-BCQGGxdd.js","filePathWithLine":".npm-global/lib/node_modules/openclaw/dist/subsystem-BCQGGxdd.js:437","method":"logToFile"}},"time":"2026-02-22T08:28:39.735Z"}
{"0":"{"subsystem":"gateway/ws"}","1":"⇄ res ✓ device.pair.list 154ms conn=8298280b…476d id=618bade1…dce5","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{"subsystem":"gateway/ws"}","parentNames":["openclaw"],"date":"2026-02-22T09:15:10.323Z","logLevelId":3,"logLevelName":"INFO","path":{"fullFilePath":"file:///home/freeman/.npm-global/lib/node_modules/openclaw/dist/subsystem-BCQGGxdd.js:438:14","fileName":"subsystem-BCQGGxdd.js","fileNameWithLine":"subsystem-BCQGGxdd.js:438","fileColumn":"14","fileLine":"438","filePath":".npm-global/lib/node_modules/openclaw/dist/subsystem-BCQGGxdd.js","filePathWithLine":".npm-global/lib/node_modules/openclaw/dist/subsystem-BCQGGxdd.js:438","method":"logToFile"}},"time":"2026-02-22T09:15:10.324Z"}
{"0":"{"subsystem":"gateway/ws"}","1":"unauthorized conn=b016c257-d3c1-4aa5-8d32-01181dfdf397 remote=127.0.0.1 client=openclaw-tui ui v2026.2.19-2 reason=device_token_mismatch","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{"subsystem":"gateway/ws"}","parentNames":["openclaw"],"date":"2026-02-22T09:16:21.890Z","logLevelId":4,"logLevelName":"WARN","path":

neon estuary
# summer falcon ```bash systemctl --user show openclaw-gateway.service -p ExecStart ``` Once yo...

{"fullFilePath":"file:///home/freeman/.npm-global/lib/node_modules/openclaw/dist/subsystem-BCQGGxdd.js:438:14","fileName":"subsystem-BCQGGxdd.js","fileNameWithLine":"subsystem-BCQGGxdd.js:438","fileColumn":"14","fileLine":"438","filePath":".npm-global/lib/node_modules/openclaw/dist/subsystem-BCQGGxdd.js","filePathWithLine":".npm-global/lib/node_modules/openclaw/dist/subsystem-BCQGGxdd.js:438","method":"logToFile"}},"time":"2026-02-22T09:16:21.891Z"}
{"0":"\u001b[38;5;167mgateway connect failed: Error: unauthorized: device token mismatch (rotate/reissue devic

summer falconBOT
#

authHash=EMPTY is the smoking gun.

It means your TUI/CLI is effectively sending an empty (or missing) operator device token, while the Gateway has a real one in ~/.openclaw/devices/paired.json (pairedHash=…). So the gateway rejects the WS connect with device token mismatch.

Before we do anything else, I need to see what’s actually inside device-auth.json without leaking the token.

A) Show the shape of device-auth.json (token redacted)

Run and paste:

D="${OPENCLAW_STATE_DIR:-$HOME/.openclaw}"

jq '{
  version,
  deviceId,
  tokenRoles: (.tokens | keys),
#
  operatorKeys: (.tokens.operator? | keys),
  operatorTokenLen: (.tokens.operator.token? // "" | tostring | length),
  operatorScopes: (.tokens.operator.scopes? // [])
} | .' "$D/identity/device-auth.json"

What I’m looking for:

  • Does deviceId here equal your identity/device.json deviceId?
  • Does it even have a tokens.operator.token?
  • Is the token length > 0?

Also paste this (safe):

jq -r .deviceId "$D/identity/device.json"
#

B) Confirm the gateway actually has an operator token for that device (len only)

D="${OPENCLAW_STATE_DIR:-$HOME/.openclaw}"
DEVICE_ID="$(jq -r .deviceId "$D/identity/device.json")"

jq -r --arg id "$DEVICE_ID" '
  .[$id] as $d
  | {
      pairedHasDevice: ($d != null),
      pairedTokenRoles: ($d.tokens | keys),
      pairedOperatorTokenLen: ($d.tokens.operator.token | length),
      pairedOperatorScopes: ($d.tokens.operator.scopes // [])
    }' "$D/devices/paired.json"

C) The “does TUI overwrite it?” test

  1. Run the sync script again (or whatever your agent ran).
#
  1. Immediately run:
jq -r '.tokens.operator.token | length' ~/.openclaw/identity/device-auth.json
  1. Then run openclaw tui until it errors, and run the same length check again.

If the length drops back to 0 after running TUI, then the client is clobbering device-auth.json on connect (very consistent with the 2026.2.19-2 regression).

D) Send your “#3” log snippet when you have it

The gateway logs usually say why it thinks it’s mismatched (wrong deviceId vs wrong role vs token mismatch).


Once you paste A + B (and the after‑TUI token length behavior), I can tell you the exact fix. Depending on what we see, it’s either:

#
  • a straightforward “device-auth.json has wrong deviceId / missing operator entry” rewrite, or
  • “2026.2.19-2 keeps rewriting device-auth.json” → at which point the honest answer is pin back to the Feb 9 build (or 2026.2.17) until the regression is fixed.
#

That log snippet answers it:

  • The gateway is rejecting the TUI connect because of reason="scope-upgrade"
  • It’s trying to upgrade your device from scopes:

operator.admin, operator.approvals, operator.pairing, operator.read

to also include:

operator.write

…and until you approve that upgrade, the WS handshake gets closed with 1008 “pairing required” (your TUI surfaces it as “device token mismatch”, but the gateway log is the ground truth).

Do this now

  1. List pending device requests (this should work since your CLI can do gateway status):
#
openclaw devices list
  1. Approve the pending repair/scope upgrade request. From your log it should be the requestId shown there (I see requestId":"01d20275-246f-4915-985d-229a7db7bdfd" in the gateway log):
openclaw devices approve 01d20275-246f-4915-985d-229a7db7bdfd
  1. Retry:
openclaw tui

If devices approve works but TUI still fails

Then you’re hitting the 2026.2.19-2 regression where the gateway rotates the token but the local cache doesn’t converge.

#

In that case, run your hash comparison again (the one you ran earlier). The key is:

  • authHash must NOT be EMPTY
  • authHash must equal pairedHash

If it’s still EMPTY, paste the redacted structure of ~/.openclaw/identity/device-auth.json (no secrets) using:

jq '{
  version,
  deviceId,
  tokenRoles: (.tokens | keys),
  operatorTokenLen: (.tokens.operator.token? // "" | tostring | length),
  operatorScopes: (.tokens.operator.scopes? // [])
}' ~/.openclaw/identity/device-auth.json
#

Also: your gateway log says the upgrade is being requested by client=gateway-client — so after you approve once, you should stop seeing new “scope-upgrade” requests for that same device.

Send your “3) in next message” full tail when you have it; but I’m 90% sure approving that specific requestId is the missing step.

neon estuary
# summer falcon Also: your gateway log says the upgrade is being requested by `client=gateway-cl...

Interesting! The hashes now match (authHash = pairedHash), but there's a scope mismatch:

Source Scopes
device-auth.json operator.admin, operator.approvals, operator.pairing
paired.json (gateway) operator.admin, operator.approvals, operator.pairing, operator.read, operator.write

The local device-auth.json is missing operator.read and operator.write scopes!

Try now:

openclaw tui

If it still fails, we may need to approve a scope upgrade request.

MY NEXT MESSAGE WILL SHOW WHAT HAPPENED WHEN I RAN DEVICES AND TUI

neon estuary
# summer falcon Also: your gateway log says the upgrade is being requested by `client=gateway-cl...

freeman@DESKTOP-P1FF11M:~$ openclaw devices list

🦞 OpenClaw 2026.2.19-2 (45d9b20) — Gateway online—please keep hands, feet, and appendages inside the shell at all times.

│
gateway connect failed: Error: unauthorized: device token mismatch (rotate/reissue device token)
â—‡
[openclaw] Failed to start CLI: Error: gateway closed (1008): unauthorized: device token mismatch (rotate/reissue device token)
Gateway target: ws://127.0.0.1:18789
Source: local loopback
Config: /home/freeman/.openclaw/openclaw.json
Bind: loopback
at Object.onClose (file:///home/freeman/.npm-global/lib/node_modules/openclaw/dist/call-DZzTR0NL.js:438:10)
at WebSocket.<anonymous> (file:///home/freeman/.npm-global/lib/node_modules/openclaw/dist/client-DoSZFvf3.js:1538:23)
at WebSocket.emit (node:events:519:28)
at WebSocket.emitClose (/home/freeman/.npm-global/lib/node_modules/openclaw/node_modules/ws/lib/websocket.js:273:10)
at Socket.socketOnClose (/home/freeman/.npm-global/lib/node_modules/openclaw/node_modules/ws/lib/websocket.js:1346:15)
at Socket.emit (node:events:519:28)
at TCP.<anonymous> (node:net:346:12)
freeman@DESKTOP-P1FF11M:~$ openclaw tui

🦞 OpenClaw 2026.2.19-2 (45d9b20) — OpenAI-compatible, not OpenAI-dependent.

openclaw tui - ws://127.0.0.1:18789 - agent main - session main
connecting | idle
gateway disconnected: unauthorized: device token mismatch (rotate/reissue device token) | idle ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
gateway connect failed: Error: unauthorized: device token mismatch (rotate/reissue device token)

summer falconBOT
#

Nice — authHash == pairedHash means the token is finally in sync. What’s left is almost certainly scopes, and there’s one important nuance:

In paired.json there are two places scopes can live:

  • device-level scopes: .[deviceId].scopes
  • token-level scopes (what the gateway actually enforces for that role/token): .[deviceId].tokens.operator.scopes

So first we need to confirm you’re comparing the right thing.

1) Show the token-level scopes on both sides (safe)

Run these and paste output:

D="${OPENCLAW_STATE_DIR:-$HOME/.openclaw}"
ID="$(jq -r .deviceId "$D/identity/device.json")"
#
echo "device-auth operator scopes:"
jq -r '.tokens.operator.scopes // []' "$D/identity/device-auth.json"

echo "paired operator token scopes:"
jq -r --arg id "$ID" '.[$id].tokens.operator.scopes // []' "$D/devices/paired.json"

echo "paired device-level scopes (for reference):"
jq -r --arg id "$ID" '.[$id].scopes // []' "$D/devices/paired.json"

2) If paired.json token scopes include operator.write but device-auth.json does not

Then TUI/CLI may be requesting an upgrade loop based on its cached scopes. Fix by syncing scopes from paired → device-auth (no tokens printed):

python3 - <<'PY'
#

That output is consistent with one specific situation:

your local CLI/TUI is still using an old operator device token (and old scopes), while the Gateway has rotated the operator token to a newer one (with operator.read + operator.write).
When that happens you get exactly what you see: unauthorized: device token mismatch on every WS connect, so openclaw devices list can’t even run.

The giveaway is your scope table: device-auth.json is missing operator.read/write, which usually means it’s still on the pre-upgrade token metadata.

Do this: force device-auth.json to exactly match paired.json (token + scopes)

Run this on the gateway host as freeman:

python3 - <<'PY'
import json, os, time, pathlib
D=os.path.expanduser("~/.openclaw")
did=json.load(open(f"{D}/identity/device.json"))["deviceId"]
paired=json.load(open(f"{D}/devices/paired.json"))
#
import json, os, time, pathlib
D=os.path.expanduser(os.environ.get("OPENCLAW_STATE_DIR","~/.openclaw"))
device=json.load(open(f"{D}/identity/device.json"))
did=device["deviceId"]
paired=json.load(open(f"{D}/devices/paired.json"))
op=paired[did]["tokens"]["operator"]
auth_path=f"{D}/identity/device-auth.json"
try: auth=json.load(open(auth_path))
except: auth={"version":1,"deviceId":did,"tokens":{}}
auth["version"]=1
auth["deviceId"]=did
auth.setdefault("tokens",{})
auth["tokens"]["operator"]={
  "token": op["token"],
  "role":"operator",
#
op=paired[did]["tokens"]["operator"]  # token+scopes from gateway truth

auth_path=f"{D}/identity/device-auth.json"
auth={"version":1,"deviceId":did,"tokens":{}}
auth["tokens"]["operator"]={
  "token": op["token"],
  "role": "operator",
  "scopes": op.get("scopes",[]),
  "updatedAtMs": int(time.time()*1000),
}

pathlib.Path(os.path.dirname(auth_path)).mkdir(parents=True, exist_ok=True)
tmp=auth_path+".tmp"
open(tmp,"w").write(json.dumps(auth,indent=2)+"\n")
os.replace(tmp,auth_path)
#
  "scopes": op.get("scopes",[]),
  "updatedAtMs": int(time.time()*1000),
}
pathlib.Path(os.path.dirname(auth_path)).mkdir(parents=True, exist_ok=True)
tmp=auth_path+".tmp"
open(tmp,"w").write(json.dumps(auth,indent=2)+"\n")
os.replace(tmp,auth_path)
os.chmod(auth_path,0o600)
print("Synced operator token+scopes into device-auth.json")
PY

Then retry:

openclaw tui
#
os.chmod(auth_path,0o600)
print("Wrote", auth_path, "for device", did)
print("Scopes:", ",".join(auth["tokens"]["operator"]["scopes"]))
PY

Then immediately retry:

openclaw tui

If tui connects, run:

#

3) If paired.json token scopes are missing operator.write

Then you need to rotate the operator token with the expanded scopes (this is the clean, supported way):

openclaw devices rotate --device ad7522285f008d32b4a866caa124eb48a0e4ddeba5ce5a7ed076af11cdc5d767 --role operator \
  --scope operator.admin --scope operator.approvals --scope operator.pairing --scope operator.read --scope operator.write

After that, run the sync script again (because 2026.2.19-2 is buggy about propagating it to device-auth.json).


Also: please paste what happens when you run these two commands (just the text output):

openclaw devices list
openclaw tui
#
openclaw devices list

…and approve any new pending “scope-upgrade” request (this version sometimes creates another one). Important: approving can rotate the operator token again, so if it suddenly breaks right after approve, just re-run the script once more.

What I need from you if it still fails after the script

Paste these safe checks (they don’t reveal tokens):

jq -r '.tokens.operator.token|length' ~/.openclaw/identity/device-auth.json
ID="$(jq -r .deviceId ~/.openclaw/identity/device.json)"
jq -r --arg id "$ID" '.[$id].tokens.operator.token|length' ~/.openclaw/devices/paired.json

And paste the newest gateway WS handshake lines:

#

That’ll confirm whether the gateway is still issuing a new scope-upgrade request every time you start the TUI.

#
tail -n 200 /tmp/openclaw/openclaw-*.log | grep -iE "handshake|token-mismatch|scope-upgrade|pairing-required|deviceId" | tail -n 60

If you’re sick of playing whack-a-mole: this is exactly why I’ve been recommending pinning off 2026.2.19-2 until the device-token regression is fixed.

neon estuary
summer falconBOT
#

Maybe — but don’t assume it. The bug you’re hitting is a known regression cluster around 2026.2.19-2 (device token + scope-upgrade flows). If Feb 21 includes a fix, upgrading is the cleanest way out. If it doesn’t, you can end up in the same loop again.

What I recommend

  1. Check what version Feb 21 actually is
npm view openclaw version
npm view openclaw versions --json | tail -n 20
  1. Backup state first (so you can instantly roll back)
tar -czf ~/openclaw-backup-$(date +%Y%m%d-%H%M%S).tgz ~/.openclaw
  1. Upgrade
neon estuary
summer falconBOT
#
npm i -g openclaw@latest
openclaw --version
  1. Immediately run the “make things consistent” trio
openclaw doctor
openclaw gateway install --force
openclaw gateway restart
  1. Test:
openclaw tui
openclaw devices list
#

If you want the safest possible approach

Do the upgrade in a separate profile first (so your working setup isn’t touched):

openclaw --profile test gateway run --port 19001

…but note: this uses a separate state dir (~/.openclaw-test), so it won’t prove that your existing broken device-auth state will self-heal—only that the new version isn’t inherently broken.

What to watch for

If the new version still prints any of these in logs/TUI:

  • device token mismatch
  • pairing required with reason=scope-upgrade

…then the fix isn’t in yet, and you should pin back to your known-good Feb 9 build (or 2026.2.17).

If you paste the output of npm view openclaw version (just the version string), I’ll tell you whether it’s likely to contain the fix based on the issue timeline.

#

I do have release notes for this, and they strongly suggest that upgrading past 2026.2.19-2 is worth it — but with one caveat.

What the Feb 21 build (2026.2.21) says it fixes (relevant to your exact symptoms)

From the upstream CHANGELOG.md, 2026.2.21 includes multiple Gateway/Pairing fixes that directly touch the loop you’re in:

  • Clear paired-device state when a client closes with device token mismatch (1008), so reconnect can re-enter pairing cleanly. (“Gateway/Pairing: clear persisted paired-device state when the gateway client closes with device token mismatch (1008)…”)
  • Backfill missing roles/scopes metadata for legacy paired devices during WS upgrade checks (fixes a reported “pairing required” regression). (“…tolerate legacy paired devices missing roles/scopes metadata… backfill metadata on reconnect. (fixes #21236)”)
  • CLI recovery for loopback deadlocks where you get stuck in pairing required and can’t run openclaw devices … to approve. (“Gateway/Pairing/CLI: … add local openclaw devices fallback recovery for loopback pairing required deadlocks…”)
  • Plus TUI-side guidance improvements for pairing-required states.

So: if “Feb 21 version” = 2026.2.21, it’s very likely to improve (or fully fix) the exact “token mismatch / scope-upgrade / can’t even run devices list” mess.

The caveat

There’s an even more direct fix for the operator scope-upgrade loop (“treat operator.admin as satisfying operator.write / other operator.* checks”) but in the changelog it’s currently listed under 2026.2.22 (Unreleased). That means it might not be in the npm release you can install today (unless you’re on beta/dev).

What I’d do (safe upgrade)

  1. Backup state:
#
tar -czf ~/openclaw-backup-$(date +%Y%m%d-%H%M%S).tgz ~/.openclaw
  1. Upgrade to the latest published npm version and check what you got:
npm i -g openclaw@latest
openclaw --version
  1. Then immediately:
openclaw doctor
openclaw gateway install --force
openclaw gateway restart
#
  1. Test:
openclaw tui
openclaw devices list

If you tell me what openclaw --version shows after upgrading (just that one line), I can tell you whether you landed on 2026.2.21 (good chance it helps) or something else — and whether you’d need beta/dev to pick up the 2026.2.22 pairing fix.

neon estuary
summer falconBOT
#

If you’re going to skip TUI for now, that’s totally workable (Telegram/Discord flows don’t require the local operator WS client in the same way). For “when is it fixed / will it self-heal”, here’s the best way to stay on top of it:

Where to track the fix

  1. GitHub issues (best signal)
    Follow/subscribe to the issues that match your symptoms:
  • “pairing required after 2026.2.19-2 / CLI + subagents broken”
  • “device token mismatch after update”

You can “Subscribe” on GitHub to get emails when a fix lands + when maintainers confirm the release version.

Start here (these are the relevant clusters we already saw):

(If you want, drop a short comment with your exact version + loopback + scope-upgrade logs; it helps maintainers confirm repro.)

#
  1. CHANGELOG
    This is where you’ll see “Gateway/Pairing” fixes called out, and which version they shipped in:
    https://github.com/openclaw/openclaw/blob/main/CHANGELOG.md

Will updating “self-heal”?

Usually yes if you do the “safe update” sequence, because newer builds include logic to:

  • clear/repair paired-device state after a token-mismatch close,
  • backfill missing role/scope metadata,
  • avoid getting stuck in loopback pairing deadlocks.

But: there are still edge cases where upgrading won’t automatically rewrite your local device-auth.json. So the safest expectation is:

  • Update may fix it automatically
  • If not, it should at least make it easy to recover (devices list/approve/rotate working again)

How to check safely without risking your working setup

When you decide to try again:

#
  1. Backup:
tar -czf ~/openclaw-backup-$(date +%Y%m%d-%H%M%S).tgz ~/.openclaw
  1. Upgrade
  2. Run:
openclaw doctor
openclaw gateway install --force
openclaw gateway restart
  1. Then try openclaw tui again.

If you want, I can also give you a tiny “canary check” list (two commands) you can run after any update to tell immediately whether this specific pairing/device-auth loop is fixed before you waste time debugging.

cursive mason
#

@summer falcon i went on telegram to talk to my bot and this happend i texted him he sended me this
HTTP 401: authentication_error: invalid api key (request_id: 05ea2ea4fa2879308c05227295991268)

neon estuary