moeru-ai/airi · warning

[chat-ws] socket error:

Error message

[chat-ws] socket error:

What it means

The chat-sync WebSocket client (VueUse useWebSocket wrapper) received a ws 'error' event and logs it via the wsErrorEvent listener. Browser WebSocket error events carry no message — the meaningful detail is the accompanying close code — so this log is the generic signal that the socket transport failed (DNS, TLS, refused connection, proxy failure, or server-side abort) independent of the app-level message handlers.

Source

Thrown at packages/stage-ui/src/libs/chat-sync/ws-client.ts:281

      if (!result.success) {
        console.warn('[chat-ws] dropped malformed newMessages payload:', result.issues[0]?.message)
        return
      }
      const payload = result.output
      for (const handler of newMessagesHandlers) {
        try {
          handler(payload)
        }
        catch (err) {
          // Same isolation principle as notifyStatus: one bad listener should
          // not silently drop messages for the rest.
          console.warn('[chat-ws] newMessages handler threw:', errorMessageFrom(err))
        }
      }
    }))

    contextDisposers.push(ctx.on(wsErrorEvent, (event) => {
      console.warn('[chat-ws] socket error:', event.body)
    }))
  }

  // The URL ref controls the user connection intent and token presence. The
  // token itself is sent only after the socket opens through Eventa.
  const ws = useWebSocket<string>(urlRef, {
    immediate: false,
    autoClose: true,
    autoReconnect: {
      retries: RECONNECT_RETRIES,
      delay: retries => computeReconnectDelay(
        Math.max(retries, authenticationFailures),
        RECONNECT_BASE_MS,
        RECONNECT_MAX_MS,
      ),
    },
    onConnected(rawWs) {
      activeSocket = rawWs

View on GitHub (pinned to b6d0809ecb)

Solutions

  1. Verify the chat sync server is running and the WebSocket URL in urlRef is correct (scheme ws/wss, host, path).
  2. Check the paired close event/code — 4001 (WS_CLOSE_UNAUTHORIZED) means token rotation is needed; 1006 means abnormal transport failure.
  3. Fix proxy config to pass through Upgrade/Connection headers and allow wss on the route.
  4. If TLS-related, renew/repair certificates; the client's autoReconnect with backoff will recover once the transport is healthy.

Example fix

// before
contextDisposers.push(ctx.on(wsErrorEvent, (event) => {
  console.warn('[chat-ws] socket error:', event.body)
}))

// after — correlate with close code for diagnosis
contextDisposers.push(ctx.on(wsErrorEvent, (event) => {
  console.warn('[chat-ws] socket error:', event.body, 'status:', status.value)
}))
ws.onError((_ws, ev) => console.warn('[chat-ws] raw error; watch onclose code for cause', ev))
Defensive patterns

Strategy: retry

Validate before calling

function isChatSyncUrlReachable(url: string): boolean {
  try {
    const parsed = new URL(url)
    return parsed.protocol === 'ws:' || parsed.protocol === 'wss:'
  }
  catch {
    return false
  }
}
// validate urlRef before connect(); reachability itself is only proven by open

Try / catch

// ws error events carry no Error object; handle at the status layer
watch(status, (s) => {
  if (s === 'CLOSED') {
    // rely on autoReconnect; surface offline state in UI
  }
})

Prevention

When it happens

Trigger: The chat sync server URL in urlRef is unreachable (wrong host/port, service down), a TLS certificate is rejected, an intermediary proxy kills the connection, or the server closes with an abnormal close code after an error. useWebSocket then schedules reconnect with the exponential backoff defined by computeReconnectDelay.

Common situations: Local dev without the chat-sync backend running; reverse proxy (Caddy/nginx) misrouting the /ws route; corporate proxy stripping Upgrade headers; expired/self-signed cert in dev; server restart causing transient error+close while autoReconnect recovers.

Related errors


AI-assisted analysis of moeru-ai/airi@b6d0809ecb (2026-08-18). Data as JSON: /api/errors/9605901f7b3041b1. Report an issue: GitHub.