{"record":{"id":"3eea590b081de540","repo":"Pumpkin-MC/Pumpkin","slug":"io-error-0-3eea59","errorCode":null,"errorMessage":"IO error: {0}","messagePattern":"IO error: (.+?)","errorType":"exception","errorClass":"WritingError","httpStatus":null,"severity":"error","filePath":"crates/pumpkin-protocol/src/ser/mod.rs","lineNumber":39,"sourceCode":"    #[error(\"EOF, Tried to read {0} but No bytes left to consume\")]\n    CleanEOF(String),\n    #[error(\"incomplete: {0}\")]\n    Incomplete(String),\n    #[error(\"too large: {0}\")]\n    TooLarge(String),\n    #[error(\"{0}\")]\n    Message(String),\n}\n\nimpl serde::de::Error for ReadingError {\n    fn custom<T: std::fmt::Display>(msg: T) -> Self {\n        Self::Message(msg.to_string())\n    }\n}\n\n#[derive(Debug, Error)]\npub enum WritingError {\n    #[error(\"IO error: {0}\")]\n    IoError(#[from] std::io::Error),\n    #[error(\"Serde failure: {0}\")]\n    Serde(String),\n    #[error(\"Packet is not supported in Minecraft version {0:?}\")]\n    UnsupportedVersion(JavaMinecraftVersion),\n    #[error(\"Failed to serialize packet: {0}\")]\n    Message(String),\n}\n\nimpl serde::ser::Error for WritingError {\n    fn custom<T: std::fmt::Display>(msg: T) -> Self {\n        Self::Serde(msg.to_string())\n    }\n}\n\nstruct NetworkReadDataSource<'a, R: NetworkReadExt + ?Sized>(&'a mut R);\n\nimpl<'a, R: NetworkReadExt + ?Sized> pumpkin_nbt::deserializer::NbtDataSource<'a>","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/Pumpkin-MC/Pumpkin/blob/8d4639e25a57c15e47448ec327c780d41bbf2356/crates/pumpkin-protocol/src/ser/mod.rs#L21-L57","documentation":"WritingError::IoError wraps a std::io::Error (via #[from]) that occurred while writing an encoded packet to the underlying transport, typically the TCP stream. The packet serialization itself succeeded; the syscall/socket layer failed. It is the lowest-level failure in the write path and often means the connection is already broken.","triggerScenarios":"Any packet write (write_all on the TCP stream) when the socket is closed or reset by the peer (BrokenPipe, ConnectionReset), the send buffer is full, or the OS reports a network error.","commonSituations":"Server broadcasting a packet to a client that just disconnected (connection reset by peer); writing to a closed keep-alive connection; network outage mid-game; socket buffer exhaustion under heavy load.","solutions":["Match on the inner io::ErrorKind: BrokenPipe/ConnectionReset/ConnectionAborted mean the peer is gone — close the connection, don't retry.","Filter dead connections out of broadcast lists before sending.","For WouldBlock/TimedOut, consider retrying or tearing down per your tolerance.","Enable TCP keepalive and handle disconnect events promptly so writes target live sockets."],"exampleFix":"// before: treating all write failures alike\npacket.write(stream).await?;\n\n// after: distinguish peer disconnects\nif let Err(WritingError::IoError(e)) = packet.write(stream).await {\n    if matches!(e.kind(), ErrorKind::BrokenPipe | ErrorKind::ConnectionReset) {\n        debug!(\"client gone: {e}\");\n        return Ok(()); // drop connection\n    }\n    return Err(e.into());\n}","handlingStrategy":"try-catch","validationCode":"// skip connections known to be closed before broadcasting\nlet targets = clients.iter().filter(|c| c.is_open()).collect::<Vec<_>>();","typeGuard":null,"tryCatchPattern":"if let Err(WritingError::IoError(e)) = packet.write(&mut stream).await {\n    match e.kind() {\n        ErrorKind::BrokenPipe | ErrorKind::ConnectionReset | ErrorKind::ConnectionAborted => {\n            debug!(\"peer disconnected: {e}\");\n            disconnect(peer_id).await;\n        }\n        _ => return Err(e.into()),\n    }\n}","preventionTips":["Remove closed connections from broadcast lists promptly via disconnect events.","Never retry writes after BrokenPipe/ConnectionReset; the socket is unusable.","Monitor network stack health if IoError rates spike (NIC issues, fd exhaustion)."],"tags":["rust","network","io","tcp","broken-pipe"],"backgroundTag":"broken-pipe","analyzedSha":"8d4639e25a57c15e47448ec327c780d41bbf2356","analyzedAt":"2026-09-09T15:32:22.916Z","contentChangedAt":"2026-09-09T15:32:22.916Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}