{"record":{"id":"9e39bd2899135a0c","repo":"valeriansaliou/sonic","slug":"brokenpipe","errorCode":null,"errorMessage":"BrokenPipe","messagePattern":"BrokenPipe","errorType":"exception","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"client/src/channel.rs","lineNumber":156,"sourceCode":"                                if let Err(error) = send_res {\n                                    // Only log an error, as this would happen if the receiver is dropped.\n                                    log_error!(\"Could not send response: {error}\");\n                                }\n                            }\n\n                            Err(error) => {\n                                if let Err(send_error) = tx.send(Err(error)) {\n                                    // Only log an error, as this would happen if the receiver is dropped.\n                                    log_error!(\"Could not send response: {send_error}\");\n                                }\n                            }\n                        }\n                    }),\n                },\n                SEND_TIMEOUT,\n            )\n            .map_err(|error| {\n                std::io::Error::new(std::io::ErrorKind::BrokenPipe, error.to_string())\n            })?;\n        self.poll_waker.wake()?;\n\n        Ok(rx)\n    }\n\n    /// Sends a command asynchronous at the protocol level (e.g. using the\n    /// `PENDING` + `EVENT` pattern).\n    pub(crate) fn send_async<T: Send + 'static>(\n        &self,\n        command: Command,\n        discriminant1: impl Into<Mode::Discriminant>,\n        make_discriminant2: impl FnOnce(&str) -> Mode::Discriminant + Send + Sync + 'static,\n        parse: impl Fn(&str) -> std::io::Result<T> + Send + 'static,\n    ) -> std::io::Result<oneshot::Receiver<std::io::Result<T>>> {\n        if command.len() > self.channel_info.buffer_size {\n            return Err(std::io::Error::new(\n                std::io::ErrorKind::InvalidInput,","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/valeriansaliou/sonic/blob/e6a72da6a532bc3f31d7d93ef1e0964a1a5d01b2/client/src/channel.rs#L138-L174","documentation":"Channel::send maps a failure on the internal oneshot/command channel (timing out after SEND_TIMEOUT or the receiver dropping) into an io::Error of kind BrokenPipe. It means the command could not be delivered to the channel worker — the connection is effectively dead.","triggerScenarios":"send_buffered -> send: the oneshot::Sender::send + timeout(SEND_TIMEOUT) path returns Err (worker stopped, receiver dropped, or timeout elapsed), which is converted via map_err to ErrorKind::BrokenPipe.","commonSituations":"Server closed or reset the connection (see the server's 'closing channel' panic); long-blocking commands exceeding SEND_TIMEOUT; using a Channel object after the underlying connection was dropped.","solutions":["Reconnect the channel/client and retry the command","Check server logs for why the channel thread closed (e.g. buffer overflow, protocol error)","Verify the server is still running and reachable (health check)","Reduce command cost or increase tolerance for slow commands so SEND_TIMEOUT is not hit"],"exampleFix":"// client\n// before\nlet rx = channel.send(cmd, disc, parse)?; // panics/errs with BrokenPipe if connection died\n// after\nmatch channel.send(cmd, disc, parse) {\n    Ok(rx) => ..., \n    Err(e) if e.kind() == std::io::ErrorKind::BrokenPipe => reconnect_and_retry(),\n    Err(e) => return Err(e),\n}","handlingStrategy":"retry","validationCode":"// detect a dead channel before sending\nif channel.is_closed() || last_send_failed {\n    reconnect();\n}","typeGuard":null,"tryCatchPattern":"match channel.send(cmd, disc, parse) {\n    Err(e) if e.kind() == std::io::ErrorKind::BrokenPipe => {\n        reconnect();\n        channel.send(cmd, disc, parse)?;\n    }\n    other => other?,\n}","preventionTips":["Wrap send with reconnect-and-retry logic","Ping periodically to detect dead connections early","Keep commands short enough to finish within SEND_TIMEOUT","Watch for server-side channel panics that kill the worker"],"tags":["client","io","broken-pipe","network"],"backgroundTag":"broken-pipe","analyzedSha":"e6a72da6a532bc3f31d7d93ef1e0964a1a5d01b2","analyzedAt":"2026-09-01T14:10:00.384Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T20:17:18.057Z"}