Pumpkin-MC/Pumpkin · error

Invalid ability value type

Error message

Invalid ability value type: {val_type}

What it means

Thrown while decoding an ability value in the Bedrock RequestAbility packet when the ability value's type byte is neither 1 (Bool) nor 2 (Float). Only these two value types are defined by the protocol, so any other byte means the packet is malformed.

Solutions

  1. Verify client protocol version matches the server's supported Bedrock version
  2. Inspect the raw packet bytes around the ability value field for offset errors
  3. If extending the protocol, add the new val_type to the match arms
  4. Reject the packet and disconnect the sender

Example fix

// before
match val_type {
    1 => Ok(Self::Bool(bool_val)),
    2 => Ok(Self::Float(float_val)),
    _ => Err(Error::new(std::io::ErrorKind::InvalidData, format!("Invalid ability value type: {val_type}"))),
}
// after (if a new type 3 is introduced upstream)
match val_type {
    1 => Ok(Self::Bool(bool_val)),
    2 => Ok(Self::Float(float_val)),
    3 => Ok(Self::NewKind(...)),
    _ => Err(Error::new(std::io::ErrorKind::InvalidData, format!("Invalid ability value type: {val_type}"))),
}
Defensive patterns

Strategy: try-catch

Validate before calling

// before calling: if you hold raw bytes, check the type byte is 1 or 2
fn is_valid_ability_type(b: u8) -> bool { b == 1 || b == 2 }

Type guard

fn as_ability_value(v: Result<AbilityValue, std::io::Error>) -> Option<AbilityValue> { v.ok() }

Try / catch

match RequestAbilityValue::read(buf) {
    Ok(v) => apply(v),
    Err(e) if e.kind() == std::io::ErrorKind::InvalidData => { log::warn!("bad ability type: {e}"); disconnect(peer); }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: RequestAbility packet containing a Value with val_type not in {1, 2}, e.g. a corrupted byte, wrong offset from a protocol mismatch, or a hand-crafted packet.

Common situations: Version mismatch between client and server protocol implementations, packet corruption, or exploit tooling sending arbitrary bytes.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at crates/pumpkin-protocol/src/bedrock/server/request_ability.rs:19

use crate::{codec::var_int::VarInt, serial::PacketRead};
use pumpkin_macros::packet;
use std::io::{Error, Read};

#[derive(Clone, Debug)]
pub enum AbilityValue {
    Bool(bool),
    Float(f32),
}

impl PacketRead for AbilityValue {
    fn read<R: Read>(buf: &mut R) -> Result<Self, Error> {
        let val_type = u8::read(buf)?;
        let bool_val = bool::read(buf)?;
        let float_val = f32::read(buf)?;
        match val_type {
            1 => Ok(Self::Bool(bool_val)),
            2 => Ok(Self::Float(float_val)),
            _ => Err(Error::new(
                std::io::ErrorKind::InvalidData,
                format!("Invalid ability value type: {val_type}"),
            )),
        }
    }
}

#[derive(PacketRead)]
#[packet(184)]
pub struct SRequestAbility {
    pub ability: VarInt,
    pub value: AbilityValue,
}

#[cfg(test)]
mod tests {
    use super::*;

View on GitHub (pinned to 8d4639e25a)