{"record":{"id":"f74100b17137a6d9","repo":"moeru-ai/airi","slug":"websocket-server-connection-failed","errorCode":null,"errorMessage":"WebSocket server connection failed","messagePattern":"WebSocket server connection failed","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/stage-ui/src/stores/mods/api/channel-server.ts","lineNumber":190,"sourceCode":"\n          connected.value = false\n\n          if (!hasEverConnected.value) {\n            // First handshake failed: clear lock so initialize() can be retried externally.\n            initializing.value = null\n          }\n          // Runtime disconnect: keep initialize/listeners for SDK auto-reconnect.\n          // Terminal failure: handled by onStateChange status === 'failed'.\n        },\n        onStateChange: ({ status }) => {\n          if (attempt !== connectionAttempt)\n            return\n\n          if (status === 'failed') {\n            // SDK entered terminal state (auth terminal / retries exhausted / autoReconnect disabled).\n            connected.value = false\n            initializing.value = null\n            console.warn('WebSocket server connection failed')\n          }\n        },\n        onReady: () => {\n          if (attempt !== connectionAttempt)\n            return\n\n          const isReconnect = hasEverConnected.value\n\n          hasEverConnected.value = true\n          connected.value = true\n          flush()\n          initializeListeners()\n\n          if (isReconnect) {\n            for (const callback of reconnectedCallbacks) {\n              try {\n                callback()\n              }","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/moeru-ai/airi/blob/677329427f32468c74b17f3ec47eeca4e05bec65/packages/stage-ui/src/stores/mods/api/channel-server.ts#L172-L208","documentation":"The channel server store's WebSocket client (server SDK Client) reached its terminal 'failed' state: authentication failed terminally, the reconnect retry budget was exhausted, or autoReconnect is disabled. connected is set to false and the initializing lock is cleared so a fresh initialize() can build a new client. This is stronger than onClose (runtime disconnect, SDK keeps auto-reconnecting) - after 'failed', nothing retries on its own.","triggerScenarios":"Handshake rejected with 401/403 due to a wrong or expired token; websocketUrl pointing at a dead or wrong endpoint until retries exhaust; autoReconnect disabled in client options; server-side auth marking the session terminal.","commonSituations":"Expired auth token after long idle; wrong server URL in settings; reverse proxy dropping WebSocket upgrades so every attempt fails; token audience mismatch after server updates.","solutions":["Verify the WebSocket server URL setting and reachability (connect manually with a ws client to the same URL)","Re-authenticate to obtain a fresh token, then call initialize() again - the cleared lock exists exactly to allow this","Check server logs for repeated auth failures or handshake rejections from this client","If retries were exhausted by a transient outage, simply call initialize() once the server is back","Confirm autoReconnect is enabled in the client options if automatic recovery is expected"],"exampleFix":"// before: one-shot init, no retry after terminal failure\nawait channelServer.initialize()\n\n// after: re-arm with backoff when the SDK gives up\nwatch(connected, (isConnected, wasConnected) => {\n  if (wasConnected && !isConnected && !initializing.value)\n    retryWithBackoff(() => channelServer.initialize())\n})","handlingStrategy":"retry","validationCode":"if (!websocketUrl.value || !token)\n  throw new Error('WebSocket server URL and auth token are required')\nawait channelServer.initialize()","typeGuard":null,"tryCatchPattern":"watch(connected, (isConnected, wasConnected) => {\n  if (wasConnected && !isConnected && !initializing.value)\n    retryWithBackoff(() => channelServer.initialize())\n})","preventionTips":["Refresh auth tokens proactively before they expire","Validate the ws/wss URL scheme and reachability before connecting","Watch the connected ref and re-arm initialize() after terminal 'failed' states - the SDK will not retry on its own","Keep autoReconnect enabled unless you own the retry loop"],"tags":["websocket","connection","authentication","terminal-state","channel-server"],"backgroundTag":"websocket-connection-failed","analyzedSha":"677329427f32468c74b17f3ec47eeca4e05bec65","analyzedAt":"2026-08-18T17:29:58.153Z","contentChangedAt":"2026-08-18T17:29:58.153Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}