Skip to content

bug(hub): Inspector Console WebSocket fails — Hub UI does not send Sec-WebSocket-Protocol header #5481

Description

@ajayaccumatic

Summary

The Hub UI's Console tab (Inspector REPL) fails to establish a WebSocket connection because the JavaScript client does not include the Sec-WebSocket-Protocol: rivet header when connecting to the inspector endpoint. The engine's guard requires this header and rejects the connection.

Environment

  • Engine version: v2.3.9 (Docker image rivetdev/engine:latest, SHA 40c1240705506)
  • Deployment: Self-hosted via Docker Compose (single node, file system persistence)
  • RivetKit: v2.3.9 (TypeScript, runner/envoy mode)
  • Browser: Chrome (latest)
  • OS: macOS

Steps to Reproduce

  1. Self-host Rivet Engine via Docker Compose with default config
  2. Connect an actor-runtime (runner mode) with a simple actor
  3. Open Hub UI at http://localhost:6420/ui
  4. Navigate to an actor → click the Console tab

Expected Behavior

The Console tab opens a WebSocket connection and provides an interactive REPL to call actor actions.

Actual Behavior

The WebSocket connection fails immediately:

Engine log:

missing_header: Missing sec-websocket-protocol header.

Browser console:

WebSocket connection to 'ws://localhost:6420/gateway/{actor_id}/inspector/connect?protocol_version=6' failed: Connection closed before receiving a handshake response

WebSocket is not open. Cannot send message. [Uint8Array(2)]

Root Cause Analysis

The engine's guard requires Sec-WebSocket-Protocol: rivet on WebSocket upgrade requests to /gateway/{id}/inspector/connect. However, the Hub UI's bundled JavaScript does not include this header when creating the WebSocket:

// What the Hub UI does (missing protocol):
new WebSocket('ws://localhost:6420/gateway/{id}/inspector/connect?protocol_version=6')

// What the engine requires:
new WebSocket('ws://...', ['rivet'])  // Sec-WebSocket-Protocol: rivet

Proof that the header is the only issue: Manually testing with the protocol header succeeds (101 Switching Protocols):

curl -i -N \
  -H "Connection: Upgrade" \
  -H "Upgrade: websocket" \
  -H "Sec-WebSocket-Version: 13" \
  -H "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==" \
  -H "Sec-WebSocket-Protocol: rivet" \
  'http://localhost:6420/gateway/{actor_id}/inspector/connect?protocol_version=6'
# → HTTP/1.1 101 Switching Protocols

What Still Works

All other Inspector features work correctly over HTTP:

  • State/Queue/Schedules/Connections/Metadata tabs ✅
  • GET /gateway/{id}/inspector/rpcs{"rpcs":["sayHi"]}
  • POST /gateway/{id}/inspector/action/sayHi with token → returns result ✅
  • POST /gateway/{id}/action/sayHi (gateway action) ✅

Suggested Fix

In the Hub UI's inspector WebSocket connection code, pass the protocol as the second argument:

new WebSocket(url, ['rivet'])

This would set the Sec-WebSocket-Protocol: rivet header on the upgrade request.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions