Skip to content

WebSocket -- Error Reference

Error conditions table and troubleshooting guide for the WebSocket component.

Error Conditions

The server can send error events or close the connection under the following conditions:

Error Message / Close CodeTriggerEvent Type
"Invalid message format"Client sent non-JSON dataerror event
"Already authenticated"Client sent authenticate when state is not UNAUTHORIZEDerror event
"Not authenticated"Client sent a non-authenticate, non-heartbeat event while unauthenticatederror event
"Authentication failed"authenticateFn returned null/falseerror event + close 4003
"Authentication error"authenticateFn threw an exceptionerror event + close 4003
"Encryption handshake failed"handshakeFn returned null/falseerror event + close 4004
Close 4004 (no error event)requireEncryption: true but no handshakeFn configuredclose 4004 only
Close 4001Auth timeout (initial: no authenticate sent)close 4001 only
Close 4001Auth in-progress timeout (authenticateFn/handshakeFn too slow)close 4001 only
Close 4002Heartbeat timeout (no messages within heartbeatTimeout)close 4002 only
Close 1001Server shutdown (wsHelper.shutdown())close 1001 only
"Invalid redis connection!"Constructor: redisConnection is falsythrown Error (startup)
"WebSocket upgrade failed"server.upgrade() returned falseHTTP 500 response

Component Errors

MethodConditionError Message
binding()application is falsy"[binding] Invalid application to bind WebSocketComponent"
binding()Node.js runtime detected"[WebSocketComponent] Node.js runtime is not supported yet. Please use Bun runtime."
resolveBindings()REDIS_CONNECTION not instanceof DefaultRedisHelper`"[WebSocketComponent][resolveBindings] Invalid instance of redisConnection
resolveBindings()AUTHENTICATE_HANDLER is falsy"[WebSocketComponent] Invalid authenticateFn to setup WebSocket server!"
registerBunHook()Bun server instance not available"[WebSocketComponent] Bun server instance not available!"

Troubleshooting

"WebSocket not initialized"

Cause: You are trying to use WebSocketServerHelper before the server has started (e.g., during DI construction).

Fix: Use the lazy getter pattern shown in Usage & Examples. Never @inject WEBSOCKET_INSTANCE directly in a constructor -- it does not exist yet at construction time.

"Invalid instance of redisConnection"

Cause: The value bound to REDIS_CONNECTION is not an instance of DefaultRedisHelper (or its subclasses RedisHelper / RedisClusterHelper).

Fix: Use RedisHelper (single instance) or RedisClusterHelper (cluster mode):

typescript
import { WebSocketBindingKeys } from '@venizia/ignis/websocket';

// Correct
this.bind({ key: WebSocketBindingKeys.REDIS_CONNECTION })
  .toValue(new RedisHelper({ name: 'websocket', host, port, password }));

// Wrong -- raw ioredis client
this.bind({ key: WebSocketBindingKeys.REDIS_CONNECTION })
  .toValue(new Redis(6379));  // This is NOT a DefaultRedisHelper!

"Invalid authenticateFn to setup WebSocket server!"

Cause: No authentication function was bound to AUTHENTICATE_HANDLER, or it was bound as null.

Fix: Bind a valid authentication function before registering the component:

typescript
import { WebSocketBindingKeys } from '@venizia/ignis/websocket';

this.bind<TWebSocketAuthenticateFn>({
  key: WebSocketBindingKeys.AUTHENTICATE_HANDLER,
}).toValue(async (data) => {
  const token = data.token as string;
  const user = await verifyJWT(token);
  return user ? { userId: user.id } : null;
});

"Node.js runtime is not supported yet"

Cause: Running the application on Node.js. The WebSocket component only supports Bun.

Fix: Either switch to Bun runtime, or use the Socket.IO Component which supports both Node.js and Bun.

"Bun server instance not available!"

Cause: The post-start hook executed but could not obtain the Bun server instance. This typically means the server failed to start.

Fix: Check server startup logs for errors. Ensure start() completes successfully before post-start hooks run.

WebSocket connects but messages are not received

Cause: Clients must send { event: 'authenticate', data: { type: '...', token: '...', publicKey?: '...' } } after connecting. Unauthenticated clients are disconnected after the timeout (default: 5 seconds) and cannot receive messages other than error events.

Fix: Ensure your client authenticates immediately after connection:

javascript
const ws = new WebSocket('wss://example.com/ws');

ws.onopen = () => {
  ws.send(JSON.stringify({
    event: 'authenticate',
    data: { type: 'Bearer', token: 'your-jwt-token' },
  }));
};

ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);
  if (msg.event === 'connected') {
    console.log('Authenticated! Client ID:', msg.data.id);
    // Now ready to send/receive events
  }
};

Client disconnected with code 4002

Cause: The client did not send any messages (including heartbeat) within the heartbeatTimeout period (default: 90 seconds).

Fix: Implement a heartbeat on the client side:

javascript
setInterval(() => {
  if (ws.readyState === WebSocket.OPEN) {
    ws.send(JSON.stringify({ event: 'heartbeat' }));
  }
}, 30000);

See Also