{"record":{"id":"06a47549a3bb5f26","repo":"Pumpkin-MC/Pumpkin","slug":"durability-correction-must-fit-in-an-i16","errorCode":null,"errorMessage":"durability correction must fit in an i16","messagePattern":"durability correction must fit in an i16","errorType":"validation","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"crates/pumpkin-protocol/src/bedrock/client/item_stack_response.rs","lineNumber":24,"sourceCode":"    serial::PacketWrite,\n};\nuse pumpkin_macros::packet;\n\n#[derive(Debug, Clone)]\npub struct ItemStackResponseSlotInfo {\n    pub requested_slot: u8,\n    pub slot: u8,\n    pub amount: u8,\n    pub item_stack_net_id: VarInt,\n    pub custom_name: String,\n    pub filtered_custom_name: String,\n    pub durability_correction: VarInt,\n}\n\nimpl PacketWrite for ItemStackResponseSlotInfo {\n    fn write<W: Write>(&self, writer: &mut W) -> Result<(), Error> {\n        if !(-32768..=32767).contains(&self.durability_correction.0) {\n            return Err(Error::new(\n                std::io::ErrorKind::InvalidInput,\n                \"durability correction must fit in an i16\",\n            ));\n        }\n        self.requested_slot.write(writer)?;\n        self.slot.write(writer)?;\n        self.amount.write(writer)?;\n        true.write(writer)?;\n        (self.item_stack_net_id.0 > 0).write(writer)?;\n        if self.item_stack_net_id.0 > 0 {\n            self.item_stack_net_id.write(writer)?;\n        }\n        self.custom_name.write(writer)?;\n        self.filtered_custom_name.write(writer)?;\n        self.durability_correction.write(writer)\n    }\n}\n","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/Pumpkin-MC/Pumpkin/blob/8d4639e25a57c15e47448ec327c780d41bbf2356/crates/pumpkin-protocol/src/bedrock/client/item_stack_response.rs#L6-L42","documentation":"Raised by ItemStackResponseSlotInfo::write when durability_correction (a VarInt) falls outside the signed 16-bit range (-32768..=32767). The Bedrock protocol encodes this field as an i16, so larger values would corrupt the packet. The write fails fast with InvalidInput instead of emitting a malformed packet.","triggerScenarios":"Constructing an ItemStackResponseSlotInfo with durability_correction.0 outside -32768..=32767 and serializing the packet with PacketWrite::write.","commonSituations":"Computing durability correction from an i32/u32 item damage value without clamping; arithmetic overflow when aggregating durability deltas.","solutions":["Clamp durability_correction to -32768..=32767 before building the packet.","Check the computation that produces the value for i32/i64 leakage into an i16 field.","Return or log a domain error instead of silently wrapping when the value doesn't fit."],"exampleFix":"// before\nlet correction = VarInt(damage_delta as i32);\n// after\nlet correction = VarInt(damage_delta.clamp(-32768, 32767) as i32);","handlingStrategy":"validation","validationCode":"fn valid_correction(v: i32) -> bool { (-32768..=32767).contains(&v) }\n// assert before building the packet:\ndebug_assert!(valid_correction(durability_correction.0));","typeGuard":"fn fits_i16(v: i64) -> Option<i16> { i16::try_from(v).ok() }","tryCatchPattern":"packet.write(&mut writer).map_err(|e| {\n    log::error!(\"item stack response encode failed: {e}\");\n    e\n})?;","preventionTips":["Clamp durability deltas to i16 at the computation site.","Prefer i16::try_from over as-casts so overflow is caught early.","Add unit tests around min/max durability values."],"tags":["protocol","bedrock","serialization","range-check"],"backgroundTag":"value-out-of-range","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"}