Skip to content

fix(events): use the WebSocket global and drop the ws dependency - #4799

Open
georgeglarson wants to merge 3 commits into
OpenHands:mainfrom
georgeglarson:refactor-drop-ws
Open

fix(events): use the WebSocket global and drop the ws dependency#4799
georgeglarson wants to merge 3 commits into
OpenHands:mainfrom
georgeglarson:refactor-drop-ws

Conversation

@georgeglarson

@georgeglarson georgeglarson commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

HUMAN:

Human verified, Screenshot attached.


AGENT:

Ported from OpenHands/typescript-client#370 (closed unmerged when that repo was archived and the client moved here; the moved files are byte-identical to the pre-fix versions, so the bug crossed repos untouched). Verified end-to-end from clients/typescript:

  • Reproduced the issue on main first: npm ci && npm run build, then the repro from the linked issue — onError receives WebSocket implementation not available on Node 22.22.2 despite globalThis.WebSocket existing.
  • Same repro on this branch: the error is gone; the client reads the global and attempts the connection.
  • npx jest src/__tests__/package-import.test.ts → 8 passed, including new cases asserting each client opens the exact expected URL against a fake globalThis.WebSocket.
  • npm test → 311 passed, 18 suites. npm run lint → 0 errors (and two fewer pre-existing any warnings in these files). npm run format:check → clean. npm run build → clean.

Why

The package is emitted as ESM, and Node 22 provides a standards-compatible globalThis.WebSocket. The conversation and bash event clients only checked window.WebSocket, then attempted require('ws') — which is unavailable in ESM — so starting either client in a Node ESM process reported WebSocket implementation not available even though the global exists. Full repro in the linked issue.

Summary

  • Read globalThis.WebSocket directly in both event clients and drop the ws dependency (every supported runtime supplies the global: browsers, and Node.js since 22.4).
  • Keep the "no implementation" condition deferred to connect() time and surfaced via the existing onError callback, so importing the package barrel still never throws.
  • Rewrite the package-import tests to delete the global for real instead of mocking ws, and add coverage pinning the URL each client opens.

Issue Number

Fixes #4846.

How to Test

cd clients/typescript
npm ci
npm run build
node --input-type=module -e "const {WebSocketCallbackClient}=await import('./dist/events/websocket-client.js'); const client=new WebSocketCallbackClient({host:'http://127.0.0.1:9',conversationId:'test',callback:()=>{},onError:(e)=>console.error('ONERROR:',e.message)}); client.start(); client.stop()"

On main this prints ONERROR: ... WebSocket implementation not available; on this branch it does not. Then npm test and npx jest src/__tests__/package-import.test.ts.

Video/Screenshots

image

Design Doc

N/A — small runtime-detection fix.

Type

  • Bug fix
  • Feature
  • Refactor
  • Breaking change
  • Docs / chore

Notes

The same change was previously reviewed as OpenHands/typescript-client#370 and went unmerged only because that repository was archived on 2026-08-30 when the client moved into this repo (OpenHands/typescript-client#371). Consumers on Node < 22.4 would lose the ws fallback, but the package already requires Node 22-era tooling throughout its CI and the global has been unflagged since Node 22.4.

georgeglarson and others added 2 commits August 31, 2026 13:34
The package is emitted as ESM, and Node 22 provides a standards-compatible
globalThis.WebSocket. The conversation and bash event clients only checked
window.WebSocket, then attempted require('ws'), which is unavailable in
ESM — so starting either client in a Node ESM process reported "WebSocket
implementation not available" even though the global exists.

Every runtime this package supports supplies the global (browsers, and
Node.js since 22.4), so read globalThis.WebSocket directly and drop the ws
dependency. The "no implementation" condition stays deferred to connect()
time and is still surfaced through the existing onError callback, so
importing the package barrel never throws.

Co-authored-by: openhands <openhands@all-hands.dev>
@georgeglarson
georgeglarson marked this pull request as ready for review September 1, 2026 08:43
@all-hands-bot

Copy link
Copy Markdown
Collaborator

🚦 CI is currently failing on this PR's latest commit.

Please fix the failing checks before OpenHands reviews it - this is re-checked automatically once you push a new commit. (A maintainer can also request @all-hands-bot as a reviewer to have it reviewed regardless of CI status.)

This is an automated check - no AI was used to generate this comment.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: WebSocket clients ignore Node's global WebSocket in ESM builds

2 participants