Bug Description
After a device scope upgrade / device approval, the Control UI enters an authentication failure loop:
- Browser holds stale local device credentials
- Gateway switches to new device token/permission state after approval
- Browser reconnects with mismatched token →
device_token_mismatch
- Frontend does not clear old device state; instead it generates a new
instanceId and retries
- Each retry produces another mismatch → another new
instanceId
- Rapid accumulation of failed attempts triggers
rate_limited: too many failed authentication attempts (retry later)
- User is locked out of Control UI; only fix is temporarily setting
gateway.auth.mode=none
Steps to Reproduce
- Use OpenClaw with Control UI (webchat) normally
- Perform a scope upgrade / device approval via the gateway
- Attempt to continue using the Control UI in the same browser session
- Observe: redirected to login page showing WebSocket URL + gateway token
- Observe in gateway logs: repeated
device_token_mismatch with incrementing instanceId values
- Eventually hits rate limit and is fully locked out
Gateway Log Evidence
Multiple distinct instanceId values appear in rapid succession:
14753151-3dac-4f0e-98a3-2be1b3327abb
17f4c557-1cd9-40e6-b3d7-54783f219f20
52abe396-df05-4daf-84e5-7f84f2f7d2bf
c69afb9e-0981-4c17-9405-27d6a2d066ca
- …
Each with authReason: device_token_mismatch, followed by authReason: rate_limited.
Root Cause Analysis
Three compounding issues:
-
No stale token cleanup on mismatch: When device_token_mismatch is detected, the frontend does not invalidate/clear the old browser device credentials. It retries with a newly generated identity instead.
-
Stale local credentials preferred over URL token: The frontend appears to prioritize its own stored device token over the fresh token embedded in the dashboard URL, perpetuating the mismatch.
-
Misleading error messaging: The error "rotate/reissue device token" implies the user should obtain a new token, when in fact the problem is stale credentials that should be discarded, not rotated.
Expected Behavior
After a scope upgrade / device approval:
- Gateway should detect token drift and signal the frontend to clear old device state
- Frontend should automatically re-authenticate with fresh credentials
- Or: the Control UI should clearly indicate "device identity expired, reconnecting…" rather than showing a login shell
Suggested Fixes
- On
device_token_mismatch, the gateway should send a signal instructing the frontend to clear stored device identity before retrying
- When generating a fresh dashboard URL with embedded token, the frontend should prioritize that over any stored device token
- Error messages during mismatch should direct users toward reconnecting / clearing state, not "rotate/reissue"
- Consider a more graceful recovery path: when a mismatch is detected post-approval, auto-invalidate the old device token server-side rather than waiting for client retry loop
Environment
- OpenClaw version: 2026.4.23
- Platform: macOS (Darwin 26.3, arm64)
- Node: v22.22.2
- Gateway: local mode, loopback bind
- Auth mode: token
- Control UI: webchat via Chrome on MacIntel
Bug Description
After a device scope upgrade / device approval, the Control UI enters an authentication failure loop:
device_token_mismatchinstanceIdand retriesinstanceIdrate_limited: too many failed authentication attempts (retry later)gateway.auth.mode=noneSteps to Reproduce
device_token_mismatchwith incrementinginstanceIdvaluesGateway Log Evidence
Multiple distinct
instanceIdvalues appear in rapid succession:14753151-3dac-4f0e-98a3-2be1b3327abb17f4c557-1cd9-40e6-b3d7-54783f219f2052abe396-df05-4daf-84e5-7f84f2f7d2bfc69afb9e-0981-4c17-9405-27d6a2d066caEach with
authReason: device_token_mismatch, followed byauthReason: rate_limited.Root Cause Analysis
Three compounding issues:
No stale token cleanup on mismatch: When
device_token_mismatchis detected, the frontend does not invalidate/clear the old browser device credentials. It retries with a newly generated identity instead.Stale local credentials preferred over URL token: The frontend appears to prioritize its own stored device token over the fresh token embedded in the dashboard URL, perpetuating the mismatch.
Misleading error messaging: The error
"rotate/reissue device token"implies the user should obtain a new token, when in fact the problem is stale credentials that should be discarded, not rotated.Expected Behavior
After a scope upgrade / device approval:
Suggested Fixes
device_token_mismatch, the gateway should send a signal instructing the frontend to clear stored device identity before retryingEnvironment