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
- Check the error's String detail and open level.dat with an NBT viewer to see which tag is missing or malformed.
- Restore level.dat from level.dat_old or a backup.
- If the world is genuinely ancient, upgrade it with an official Minecraft client first, then load it in Pumpkin.
- 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
- Keep level.dat_old as a fallback; never delete it
- Gracefully shut down the server to avoid truncated level.dat writes
- Migrate very old worlds through a vanilla client before loading
- After third-party tools touch level.dat, verify it still has DataVersion and version
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
- Serde error
- Length too large
- Failed to decode varint - value too large
- Failed to decode varlong - value too large
- unexpected EOF
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)