Pumpkin-MC/Pumpkin · critical · WorldInfoError
Io error
Error message
Io error: {0} What it means
WorldInfoError::IoError(std::io::ErrorKind) is returned when reading or writing world info (level.dat / level.dat_old) fails at the filesystem level. The io::Error is converted into this variant via From<std::io::Error>, keeping only the ErrorKind. It wraps low-level OS failures such as file-not-found, permission-denied, or interrupted reads.
Solutions
- Check that the level folder contains a readable level.dat (and level.dat_old) with correct permissions.
- Run the server under a user with read/write access to the world directory and ensure the disk has free space.
- Match on the returned ErrorKind (NotFound, PermissionDenied, etc.) to apply the appropriate fix or retry.
- Restore level.dat from level.dat_old or a backup if the file is corrupt or zero-length.
Example fix
// before: ignoring the kind and crashing on any io failure
let level = reader.read_world_info(&path)?;
// after: handle known io kinds gracefully
match reader.read_world_info(&path) {
Err(WorldInfoError::IoError(std::io::ErrorKind::NotFound)) => init_fresh_world(&path),
other => other?,
} Defensive patterns
Strategy: try-catch
Validate before calling
fn level_dat_readable(level_folder: &Path) -> std::io::Result<()> {
let f = std::fs::File::open(level_folder.join("level.dat"))?;
f.metadata()?.permissions().readonly();
Ok(())
} Type guard
fn world_info_present(level_folder: &Path) -> bool {
level_folder.join("level.dat").is_file()
} Try / catch
match reader.read_world_info(&path) {
Err(WorldInfoError::IoError(kind)) => match kind {
std::io::ErrorKind::NotFound => init_new_world(&path),
std::io::ErrorKind::PermissionDenied => eprintln!("fix permissions on {}", path.display()),
_ => eprintln!("io failure reading world info: {kind:?}"),
},
other => { other?; }
} Prevention
- Ensure the server process user owns or can read/write the world directory
- Check disk free space before saves
- Back up level.dat before running external tools against it
- On Windows, avoid concurrent access by backup/AV software
When it happens
Trigger: AnvilLevelInfo's WorldInfoReader::read_world_info or WorldInfoWriter::write_world_info opens/reads/writes the level folder's level.dat (or its backup) and the underlying std::io operation fails; the From impl at world_info/mod.rs:381 maps it to IoError.
Common situations: level.dat missing from a partially-copied world folder; read-only server directory or insufficient permissions; disk full during a level.dat save; file locked by another process (e.g. backup tool) on Windows.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
AI-assisted analysis of Pumpkin-MC/Pumpkin@8d4639e25a (2026-09-09).
Data as JSON: /api/errors/8c1e130cf86d8fd5.
Report an issue: GitHub.
Appendix: source
Thrown at crates/pumpkin-world/src/world_info/mod.rs:363
seed: Seed,
generator: &crate::generation::generator::VanillaGenerator,
) -> Self {
let mut data = Self::default(seed);
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 {View on GitHub (pinned to 8d4639e25a)