Pumpkin-MC/Pumpkin · critical · WorldInfoError

Deserialization error

Error message

Deserialization error: {0}

What it means

WorldInfoError::DeserializationError(String) is returned when world info was found but its NBT contents could not be converted into the expected structures. The String carries the detail, e.g. 'Missing DataVersion' or 'Missing version' when level.dat lacks those tags (anvil.rs:40-67). It covers structural NBT mismatches rather than io or version-range failures.

Solutions

  1. Check the error's String detail and open level.dat with an NBT viewer to see which tag is missing or malformed.
  2. Restore level.dat from level.dat_old or a backup.
  3. If the world is genuinely ancient, upgrade it with an official Minecraft client first, then load it in Pumpkin.
  4. Regenerate the world if no backup exists and the file is unreadable garbage.

Example fix

// before: trusting any level.dat
let level = reader.read_world_info(&path)?;
// after: fall back to the backup on deserialization failure
let level = match reader.read_world_info(&path) {
    Err(WorldInfoError::DeserializationError(msg)) => {
        warn("level.dat corrupt: {msg}; trying backup");
        reader.read_world_info(&path.with_file_name("level.dat_old"))?
    }
    other => other?,
};
Defensive patterns

Strategy: try-catch

Validate before calling

fn level_dat_parses(path: &Path) -> bool {
    std::fs::File::open(path).ok()
        .and_then(|f| pumpkin_nbt::from_reader(gz_decode(f)).ok())
        .is_some()
}

Type guard

fn has_required_tags(root: &NbtCompound) -> bool {
    root.get_compound("Data")
        .map(|d| d.get_int("DataVersion").is_some() && d.get_int("version").is_some())
        .unwrap_or(false)
}

Try / catch

match reader.read_world_info(&path) {
    Err(WorldInfoError::DeserializationError(msg)) => {
        warn!("level.dat unreadable ({msg}); falling back to level.dat_old");
        reader.read_world_info(&path.with_file_name("level.dat_old"))?;
    }
    other => { other?; }
}

Prevention

When it happens

Trigger: check_data_version or check_level_version find no 'DataVersion'/'version' int tag in the Data compound; NBT parsing of level.dat fails or a required compound/tag is absent while converting to LevelData; the seed lookup fails to parse stored settings.

Common situations: Corrupt or truncated level.dat (e.g. crash mid-save, failed gzip); extremely old worlds written before DataVersion existed; third-party tools rewriting level.dat with a different schema.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — 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/0160e0b3797d2df8. Report an issue: GitHub.

Appendix: source

Thrown at crates/pumpkin-world/src/world_info/mod.rs:367

        let spawn_pos = generator.find_spawn_position();
        data.spawn_x = spawn_pos.0.x;
        data.spawn_z = spawn_pos.0.z;
        data
    }

    pub const fn set_pos(&mut self, x: i32, z: i32) {
        self.spawn_x = x;
        self.spawn_z = z;
    }
}

#[derive(Error, Debug)]
pub enum WorldInfoError {
    #[error("Io error: {0}")]
    IoError(std::io::ErrorKind),
    #[error("Info not found!")]
    InfoNotFound,
    #[error("Deserialization error: {0}")]
    DeserializationError(String),
    #[error(
        "No world seed found: neither level.dat nor data/minecraft/world_gen_settings.dat contains one"
    )]
    MissingWorldSeed,
    #[error("Serialization error: {0}")]
    SerializationError(String),
    #[error("Unsupported world data version: {0}")]
    UnsupportedDataVersion(i32),
    #[error("Unsupported world level version: {0}")]
    UnsupportedLevelVersion(i32),
}

impl From<std::io::Error> for WorldInfoError {
    fn from(value: std::io::Error) -> Self {
        match value.kind() {
            std::io::ErrorKind::NotFound => Self::InfoNotFound,
            value => Self::IoError(value),

View on GitHub (pinned to 8d4639e25a)