{"record":{"id":"88db2ac53e81ee56","repo":"Pumpkin-MC/Pumpkin","slug":"multiple-players-dragging-in-a-container-at-once","errorCode":null,"errorMessage":"Multiple players dragging in a container at once","messagePattern":"Multiple players dragging in a container at once","errorType":"exception","errorClass":"InventoryError","httpStatus":null,"severity":"warning","filePath":"crates/pumpkin-inventory/src/error.rs","lineNumber":21,"sourceCode":"/// Errors that can occur during inventory operations.\n///\n/// These errors represent various failure conditions when handling inventory\n/// interactions, such as invalid slot indices, permission issues, or protocol errors.\n#[derive(Error, Debug)]\npub enum InventoryError {\n    /// Failed to acquire a lock on an inventory or slot.\n    #[error(\"Unable to lock\")]\n    LockError,\n    /// The specified slot index is invalid or out of bounds.\n    #[error(\"Invalid slot\")]\n    InvalidSlot,\n    /// A player attempted to interact with a container that is closed.\n    ///\n    /// The parameter is the player's entity ID.\n    #[error(\"Player '{0}' tried to interact with a closed container\")]\n    ClosedContainerInteract(i32),\n    /// Multiple players attempted to drag items in the same container simultaneously.\n    #[error(\"Multiple players dragging in a container at once\")]\n    MultiplePlayersDragging,\n    /// Drag operation was performed out of order (e.g., end before start).\n    #[error(\"Out of order dragging\")]\n    OutOfOrderDragging,\n    /// The received inventory packet is malformed or invalid.\n    #[error(\"Invalid inventory packet\")]\n    InvalidPacket,\n    /// The player lacks permission to perform this inventory operation.\n    #[error(\"Player does not have enough permissions\")]\n    PermissionError,\n}\n","sourceCodeStart":3,"sourceCodeEnd":33,"githubUrl":"https://github.com/Pumpkin-MC/Pumpkin/blob/8d4639e25a57c15e47448ec327c780d41bbf2356/crates/pumpkin-inventory/src/error.rs#L3-L33","documentation":"InventoryError::MultiplePlayersDragging is returned when multiple players attempt to perform a drag-style item distribution in the same container at the same time. Drag interactions are stateful (a drag must span start/middle/end packets), so the library forbids interleaved drags from different players to keep distributions consistent.","triggerScenarios":"Two players sending Drag-packet sequences (left/medium/right drag) targeting the same open container concurrently; a second drag starting before the first player's drag completes with its End packet.","commonSituations":"Busy public chests where several players drag-split stacks simultaneously; clients that abort drags without sending the End packet, leaving drag state stuck.","solutions":["Reject the second drag with this error and require the client to restart its drag","Add a timeout that clears stale drag state so a missing End packet cannot block future drags","Serialize drag handling per container and cancel the first drag when a second player initiates one","Log which player IDs conflicted to spot abusive clients"],"exampleFix":"// before\ncontainer.handle_drag(player_id, drag)?;\n// after\nmatch container.handle_drag(player_id, drag) {\n    Err(InventoryError::MultiplePlayersDragging) => {\n        player.send_message(\"Another player is dragging items; try again.\");\n    }\n    r => r?,\n}","handlingStrategy":"try-catch","validationCode":"fn drag_allowed(container: &Container, player_id: i32) -> bool {\n    match container.active_drag() {\n        None => true,\n        Some(d) => d.player_id == player_id,\n    }\n}","typeGuard":null,"tryCatchPattern":"match container.handle_drag(player_id, drag) {\n    Err(InventoryError::MultiplePlayersDragging) => {\n        player.send_message(\"Another player is dragging; try again shortly.\");\n    }\n    r => r?,\n}","preventionTips":["Add a timeout that clears stale drag state when an End packet never arrives","Serialize drag handling per container and reject interleaved drags early","Track the dragging player ID so the same player can continue its own drag","Log conflicting player IDs to identify abusive or broken clients"],"tags":["inventory","drag","concurrency","protocol","rust"],"backgroundTag":"conflicting-concurrent-operation","analyzedSha":"8d4639e25a57c15e47448ec327c780d41bbf2356","analyzedAt":"2026-09-09T15:32:22.916Z","contentChangedAt":"2026-09-09T15:32:22.916Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}