Pumpkin-MC/Pumpkin · error

missing inventory transaction type

Error message

missing inventory transaction type

What it means

Thrown while decoding InventoryTransactionPacket when the optional-presence bool preceding the transaction type is false. The protocol signals each following field's presence with a boolean; the library requires the transaction type to always be present and rejects the packet otherwise.

Solutions

  1. Check for earlier misalignment in the packet decode (actions/legacy slots lengths).
  2. Ensure the client serializes the presence bool as true before the transaction type.
  3. Compare protocol version field layouts between client and server.
  4. Dump the raw packet bytes and hand-decode from the start to locate the desync.

Example fix

// sender before: omitting presence flag
write_varuint(buf, transaction_type)?;
// after
buf.push(0x01); // presence bool: true
write_varuint(buf, transaction_type)?;
Defensive patterns

Strategy: try-catch

Try / catch

match InventoryTransactionPacket::read(buf) {
    Err(e) if e.to_string().contains("missing inventory transaction type") => {
        log::warn!("transaction packet missing required type flag: {e}; dropping");
        // inspect stream alignment before blaming the client
    }
    other => other?,
}

Prevention

When it happens

Trigger: Triggered by InventoryTransactionPacket::read when bool::read(buf) returns false right before the transaction_type VarUInt is read.

Common situations: Stream desynchronization (a prior field misread consuming a wrong number of bytes), a client writing the packet without the presence flag, protocol version mismatch in field ordering.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of Pumpkin-MC/Pumpkin@8d4639e25a (2026-09-09). Data as JSON: /api/errors/17b5cf3c03afc29d. Report an issue: GitHub.

Appendix: source

Thrown at crates/pumpkin-protocol/src/bedrock/server/inventory_transaction.rs:187

    pub transaction_data: TransactionData,
}

impl PacketRead for SInventoryTransaction {
    fn read<R: Read>(buf: &mut R) -> Result<Self, Error> {
        let legacy_request_id = VarInt::read(buf)?;

        let has_legacy_slots = bool::read(buf)?;
        let mut legacy_set_item_slots = Vec::new();
        if has_legacy_slots {
            let len = collection_length(buf, "legacy item slot groups")?;
            legacy_set_item_slots.reserve(len);
            for _ in 0..len {
                legacy_set_item_slots.push(LegacySetItemSlot::read(buf)?);
            }
        }

        if !bool::read(buf)? {
            return Err(Error::new(
                ErrorKind::InvalidData,
                "missing inventory transaction type",
            ));
        }
        let transaction_type = VarUInt::read(buf)?;

        if !bool::read(buf)? {
            return Err(Error::new(
                ErrorKind::InvalidData,
                "missing inventory action data",
            ));
        }
        let actions_len = collection_length(buf, "inventory actions")?;
        let mut actions = Vec::with_capacity(actions_len);
        for _ in 0..actions_len {
            actions.push(InventoryAction::read(buf)?);
        }
        let has_value = !actions.is_empty();

View on GitHub (pinned to 8d4639e25a)