Skip to content

Control UI device token mismatch loop after scope upgrade causes rate-limit lockout #71609

Description

@ricksayhi

Bug Description

After a device scope upgrade / device approval, the Control UI enters an authentication failure loop:

  1. Browser holds stale local device credentials
  2. Gateway switches to new device token/permission state after approval
  3. Browser reconnects with mismatched token → device_token_mismatch
  4. Frontend does not clear old device state; instead it generates a new instanceId and retries
  5. Each retry produces another mismatch → another new instanceId
  6. Rapid accumulation of failed attempts triggers rate_limited: too many failed authentication attempts (retry later)
  7. User is locked out of Control UI; only fix is temporarily setting gateway.auth.mode=none

Steps to Reproduce

  1. Use OpenClaw with Control UI (webchat) normally
  2. Perform a scope upgrade / device approval via the gateway
  3. Attempt to continue using the Control UI in the same browser session
  4. Observe: redirected to login page showing WebSocket URL + gateway token
  5. Observe in gateway logs: repeated device_token_mismatch with incrementing instanceId values
  6. 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:

  1. 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.

  2. 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.

  3. 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

  1. On device_token_mismatch, the gateway should send a signal instructing the frontend to clear stored device identity before retrying
  2. When generating a fresh dashboard URL with embedded token, the frontend should prioritize that over any stored device token
  3. Error messages during mismatch should direct users toward reconnecting / clearing state, not "rotate/reissue"
  4. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions