{"record":{"id":"8743a307bc8f41ea","repo":"herdrdev/herdr","slug":"server-closed-connection","errorCode":null,"errorMessage":"server closed connection","messagePattern":"server closed connection","errorType":"error_code","errorClass":"ClientError::ConnectionLost","httpStatus":null,"severity":"error","filePath":"src/client/mod.rs","lineNumber":337,"sourceCode":"        }\n    }\n}\n\nimpl std::error::Error for ClientError {\n    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {\n        match self {\n            ClientError::ConnectionFailed(err) => Some(err),\n            ClientError::ConnectionLost(err) => Some(err),\n            ClientError::Protocol(err) => Some(err),\n            _ => None,\n        }\n    }\n}\n\nimpl From<protocol::FramingError> for ClientError {\n    fn from(err: protocol::FramingError) -> Self {\n        match err {\n            protocol::FramingError::UnexpectedEof => ClientError::ConnectionLost(io::Error::new(\n                io::ErrorKind::UnexpectedEof,\n                \"server closed connection\",\n            )),\n            protocol::FramingError::Io(err) => ClientError::ConnectionLost(err),\n            err => ClientError::Protocol(err),\n        }\n    }\n}\n\n// ---------------------------------------------------------------------------\n// Terminal setup / restore\n// ---------------------------------------------------------------------------\n\n/// Sets up the terminal for client mode (raw mode, optional mouse, keyboard enhancements).\n///\n/// Returns a guard that restores the terminal when dropped.\nfn setup_terminal(mouse_capture: bool) -> io::Result<TerminalGuard> {\n    setup_terminal_with_capabilities(true, mouse_capture)","sourceCodeStart":319,"sourceCodeEnd":355,"githubUrl":"https://github.com/herdrdev/herdr/blob/f457cff4f2648eee85d176f8a41861241d4e8428/src/client/mod.rs#L319-L355","documentation":"The client's From<protocol::FramingError> impl maps FramingError::UnexpectedEof to ClientError::ConnectionLost with UnexpectedEof and the message 'server closed connection' (src/client/mod.rs:337). UnexpectedEof means the framed stream ended mid-read — the TCP/local socket was closed by the peer before a complete message frame arrived.","triggerScenarios":"Any client read path decoding a protocol frame hits EOF because the herdr server process exited, crashed, or closed the socket while the client was reading (handshake, event loop, or attach stream).","commonSituations":"Server killed or OOM-killed mid-session, herdr update restarting the server, server panic, or a socket path pointing at a dead server's stale socket being cleaned up.","solutions":["Check that the herdr server is running: herdr status or herdr server list; restart with herdr daemon start / herdr server start","Inspect server logs for a crash or panic at the moment of disconnect","Clear stale sockets if the server died without cleanup, then reconnect","If it recurs, report the server-side panic backtrace from the logs"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// verify the server is reachable before connecting\nherdr status || herdr daemon start","typeGuard":"fn is_connection_lost(e: &ClientError) -> bool {\n    matches!(e, ClientError::ConnectionLost(err) if err.kind() == io::ErrorKind::UnexpectedEof)\n}","tryCatchPattern":"match client.run() {\n    Err(e) if is_connection_lost(&e) => reconnect_with_backoff(),\n    r => r,\n}","preventionTips":["Monitor the server process and restart it automatically","Handle ConnectionLost by reconnecting rather than surfacing a fatal error"],"tags":["network","connection","protocol","eof","rust"],"backgroundTag":"connection-closed-by-peer","analyzedSha":"f457cff4f2648eee85d176f8a41861241d4e8428","analyzedAt":"2026-08-28T15:41:09.197Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}