Skip to content

Error Reference

Every error condition the WebSocket component and helper can raise, plus fixes for the ones you'll actually hit.

Error conditions

Error Message / Close CodeTriggerEvent Type
"Invalid message format"Client sent non-JSON dataerror event
"Already authenticated"Client sent authenticate while state was 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 threwerror 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 - no authenticate sent within authTimeoutclose 4001 only
Close 4001Auth in-progress timeout - authenticateFn/handshakeFn slower than authTimeout * 3close 4001 only
Close 4002Heartbeat timeout - no messages within heartbeatTimeoutclose 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-level 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 AbstractRedisHelper"[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: WebSocketServerHelper was accessed before the server started - e.g. during DI construction.
  • Fix: Use the lazy getter pattern from Usage & Examples. Never @inject WEBSOCKET_INSTANCE in a constructor - it does not exist yet at that point.

"Invalid instance of redisConnection"

  • Cause: The value bound to REDIS_CONNECTION is not an AbstractRedisHelper instance - i.e. not a RedisSingleHelper, RedisClusterHelper, or RedisSentinelHelper.
  • Fix: Bind one of the concrete topology helpers, not a raw ioredis client.
typescript
import { WebSocketBindingKeys } from '@venizia/ignis/websocket';

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

// Wrong: raw ioredis client, not an AbstractRedisHelper
this.bind({ key: WebSocketBindingKeys.REDIS_CONNECTION }).toValue(new Redis(6379));

"Invalid authenticateFn to setup WebSocket server!"

  • Cause: No function 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 user = await verifyJWT(data.token as string);
    return user ? { userId: user.id } : null;
  },
);

"Node.js runtime is not supported yet"

  • Cause: Running on Node.js. The WebSocket component only supports Bun.
  • Fix: Switch to Bun, or use the Socket.IO Component instead - it supports both runtimes.

"Bun server instance not available!"

  • Cause: The post-start hook ran but could not obtain the Bun server instance - typically the server failed to start.
  • Fix: Check server startup logs. Confirm start() completes successfully before post-start hooks run.

WebSocket connects but no messages arrive

  • Cause: The client never sent { event: 'authenticate', data: { ... } }. Unauthenticated clients are disconnected after authTimeout (5s default) and receive only error events.
  • Fix: Authenticate immediately after the connection opens.
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);
  }
};

Client disconnected with code 4002

  • Cause: No message (including heartbeat) arrived within heartbeatTimeout (90s default).
  • Fix: Send a heartbeat on an interval shorter than the timeout.
javascript
setInterval(() => {
  if (ws.readyState === WebSocket.OPEN) {
    ws.send(JSON.stringify({ event: 'heartbeat' }));
  }
}, 30000);

See also