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 = rawWsView on GitHub (pinned to b6d0809ecb)
Solutions
- Verify the chat sync server is running and the WebSocket URL in urlRef is correct (scheme ws/wss, host, path).
- Check the paired close event/code — 4001 (WS_CLOSE_UNAUTHORIZED) means token rotation is needed; 1006 means abnormal transport failure.
- Fix proxy config to pass through Upgrade/Connection headers and allow wss on the route.
- 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
- Validate the WS URL shape before connecting.
- Keep autoReconnect with backoff enabled (already configured via computeReconnectDelay).
- Correlate error logs with close codes — 4001 needs token rotation, 1006 is transport.
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
- [chat-ws] ws error event:
- [chat-sync] pullMessages failed for
- [chat-sync] DELETE /api/v1/chats failed for
- [chat-sync] listChats failed; skipping reconcile this round:
- [chat-ws] dropped malformed newMessages payload:
AI-assisted analysis of moeru-ai/airi@b6d0809ecb (2026-08-18).
Data as JSON: /api/errors/9605901f7b3041b1.
Report an issue: GitHub.