{"record":{"id":"ed8da17b382564cf","repo":"zed-industries/zed","slug":"cloud-websocket-error-error","errorCode":null,"errorMessage":"Cloud WebSocket error: {error}","messagePattern":"Cloud WebSocket error: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/cloud_api_client/src/websocket/web.rs","lineNumber":34,"sourceCode":"pub struct Connection {\n    rx: SplitStream<WebSocket>,\n}\n\nimpl Connection {\n    fn new(websocket: WebSocket) -> Self {\n        let (_, rx) = websocket.split();\n        Self { rx }\n    }\n\n    pub fn spawn(self, cx: &App) -> (MessageStream, Task<()>) {\n        let mut rx = self.rx;\n        let (message_tx, message_rx) = unbounded();\n        let task = cx.spawn(async move |_cx| {\n            while let Some(frame) = rx.next().await {\n                let frame = match frame {\n                    Ok(frame) => frame,\n                    Err(error) => {\n                        let error = anyhow!(\"Cloud WebSocket error: {error}\");\n                        if message_tx.unbounded_send(Err(error)).is_err() {\n                            break;\n                        }\n                        continue;\n                    }\n                };\n                if !forward_frame(frame, &message_tx) {\n                    break;\n                }\n            }\n        });\n\n        (message_rx.into_stream().boxed(), task)\n    }\n}\n\nimpl CloudApiClient {\n    pub fn connect(self: &std::sync::Arc<Self>, cx: &App) -> Result<Task<Result<Connection>>> {","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/zed-industries/zed/blob/bc538def4545534201bbfcac4e95ac34ea6501b6/crates/cloud_api_client/src/websocket/web.rs#L16-L52","documentation":"The Cloud WebSocket reader task forwards any frame-level read error from the websocket stream into the message channel wrapped as 'Cloud WebSocket error: {error}'. It signals a failed or broken websocket frame after the connection was established.","triggerScenarios":"rx.next() yields Err: connection reset mid-frame, TLS renegotiation failure, protocol violation from an intermediary, or the server aborting the websocket handshake state machine.","commonSituations":"Network interruptions during long-lived cloud sessions; proxies with idle timeouts killing websockets; MTU/fragmentation issues on VPN links.","solutions":["Treat the error as a disconnect: re-establish the Cloud WebSocket connection","Enable websocket keep-alive/ping so intermediaries do not idle-timeout the stream","Check network stability and any proxy websocket idle timeout settings"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"while let Some(frame) = message_rx.next().await {\n    match frame {\n        Ok(frame) => handle_frame(frame),\n        Err(err) if err.to_string().starts_with(\"Cloud WebSocket error\") => {\n            // stream is dead: reconnect with backoff instead of continuing\n            reconnect_with_backoff(&client, cx).await;\n        }\n        Err(err) => log::error!(\"unexpected stream error: {err:#}\"),\n    }\n}","preventionTips":["Design consumers to reconnect on stream errors rather than propagate them","Keep websocket ping/pong alive through proxies with idle timeouts","Distinguish frame errors (reconnect) from auth errors (stop)"],"tags":["websocket","network","cloud"],"backgroundTag":null,"analyzedSha":"bc538def4545534201bbfcac4e95ac34ea6501b6","analyzedAt":"2026-08-16T07:30:46.435Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}