openclaw / openclaw/openclaw-windows-node

[Bug]: Operator RPC can be sent before connect/hello-ok, causing 1008 PolicyViolation

Open
#1,418 1 comment 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

clawsweeper:fix-shape-clear clawsweeper:queueable-fix clawsweeper:source-repro impact:ux-friction issue-rating: 🦞 diamond lobster no-stale P1
Dominant language
C#
Stars
2.1k
Forks
295
Avg merge
1d 6h
Merged PRs (30d)
99

Description

Context

This issue was originally reported in:

openclaw/openclaw#148115

Core triage determined that the Gateway behavior is correct and that the defect belongs to the Windows Companion client maintained in this repository.

The original issue was closed as out-of-repository scope, not because the reported race was considered invalid.

Summary

During Windows Companion startup or reconnect, the operator WebSocket can send RPCs such as node.list, device.pair.list, or models.list before the required connect handshake completes.

The Gateway then correctly rejects the request and closes the socket with:

1008 PolicyViolation: invalid handshake: first request must be connect

Expected behavior

Application RPCs should only be sent after the operator WebSocket has completed the connect handshake and received hello-ok.

Known-good sequence:

operator socket opened
→ connect sent
→ hello-ok received
→ Handshake complete
→ models.list / node.list / other RPCs

Actual behavior

During reconnects, the operator WebSocket can be open before its protocol handshake is complete.

Another connection event may then trigger an RPC on the operator socket before connect has been sent.

Observed example:

04:09:23.717 operator: Connecting to gateway
04:09:23.871 node:     Sending connect (role=node)
04:09:24.310 node:     Received hello-ok
04:09:24.314 operator: gateway connected, waiting for challenge...
04:09:24.315 operator: Received connect.challenge
04:09:24.316 node:     Node status changed: Connected
04:09:24.317 operator: node.list failed: invalid handshake: first request must be connect
04:09:24.318 operator: Server closed connection: PolicyViolation (1008)
04:09:24.321 operator: gateway reconnecting in 4548ms
04:09:26.953 operator: Sending connect

The node.list RPC was sent before the operator socket sent connect.

A startup variant was also observed:

03:16:03.489 operator: gateway connected, waiting for challenge...
03:16:03.520 [ChatBridge] proactive: requesting models.list and sessions.list
03:16:03.523 Sending frame: models.list
03:16:03.541 PolicyViolation - first request must be connect
03:16:05.625 Sending connect

Frequency

Historical Companion logs contained 29 occurrences of this 1008 PolicyViolation.

  • 28 occurred during reconnect:
    • 22 involved node.list
    • 6 involved device.pair.list
  • 1 startup occurrence involved models.list

After an unrelated WSL lifecycle issue was fixed, a stable 5.5-minute capture showed:

  • zero reconnects
  • zero PolicyViolation events
  • zero first request must be connect
  • zero connection failures
  • stable operator/node sockets

Version

  • Windows Companion: 2026.9.3
  • Companion commit: 84928c43
  • Gateway: 2026.9.2
  • Gateway protocol: 4
  • OS: Windows 11

Source-level evidence

The Companion currently exposes gateway readiness as:

IsConnectedToGateway => IsConnected

However, IsConnected appears to represent WebSocket-open state rather than protocol-handshake completion.

A separate handshake state already exists as _hasHandshakeSnapshot.

SendTrackedRequestAsync also appears to check socket connectivity without requiring hello-ok completion.

Observed request paths include:

  • RequestNodesAsync
  • RequestDevicePairListAsync
  • proactive models.list startup requests

This allows RPC admission during the window where the socket is open but the operator handshake has not completed yet.

Possible fix

Gateway readiness could require both socket connectivity and handshake completion, for example:

public bool IsConnectedToGateway =>
    IsConnected && Volatile.Read(ref _hasHandshakeSnapshot);

It may also be useful to add a defensive handshake-readiness guard in tracked RPC send paths so application RPCs cannot be sent before hello-ok.

Gateway behavior

The Gateway appears to be behaving correctly.

It requires the first application frame to be connect, and rejects other requests with 1008 PolicyViolation.

The original core triage explicitly identified the Windows Companion as the correct repair location.

Impact

Severity: intermittent reconnect failure / degraded connection reliability.

No data loss was observed.

A failed operator connection is discarded and retried after approximately 4.5 seconds.

During reconnect activity, the Windows Companion may show user-facing states such as:

  • Authentication failed
  • Transport error
  • Gateway connection failed

Reproduction

A deterministic current-main reproduction has not yet been performed.

The evidence is based on:

  • Windows Companion logs
  • Gateway journal
  • Windows process/socket inspection
  • Companion source review
  • repeated historical occurrences

Related issue

openclaw/openclaw#148115

Screenshots

Screenshots below show the user-visible connection/reconnect failure states.

Image Image Image

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing IsConnectedToGateway, _hasHandshakeSnapshot, and SendTrackedRequestAsync, then inspect RequestNodesAsync, RequestDevicePairListAsync, and the proactive models.list request path. Confirm how hello-ok updates handshake state and how reconnect events admit RPCs. Done means application RPCs cannot be sent until the operator connect handshake completes, with coverage for the startup or reconnect race if the existing test structure supports it.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
desktop, networking
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.