Skip to content

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

Description

@jaser-deli

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1Urgent regression or broken agent/channel workflow affecting real users now.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.clawsweeper:queueable-fixClawSweeper marked this issue as an existing queue_fix_pr work candidate.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:ux-frictionUser-facing flow adds avoidable confusion or support burden without fully blocking progress.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.no-staleExempts this issue from stale automation.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions