a-b-street/abstreet · error

Can't write_binary( )

Error message

Can't write_binary({}): {}

What it means

write_binary bincode-serializes obj to a BufWriter over a newly created file at path, panicking with this message on failure. The path must end with .bin (otherwise maybe_write_binary panics differently), and parent directories are auto-created first. This panic fires when the file can't be created or bincode serialization into the writer fails.

Solutions

  1. Check available disk space and quotas, and confirm the output filesystem is writable.
  2. Verify the path ends with .bin and its parent is a writable directory (write_binary creates it, but permission is still needed).
  3. If serializing a very large object, raise the bincode size limit (bincode::config with no_limit) or write via a Result-returning path.
  4. Fix directory permissions (chmod/chown) or choose a different output location.

Example fix

// before
abstio::write_binary("/mnt/ro/out/data.bin".to_string(), &dataset);

// after
let path = "/mnt/ro/out/data.bin";
match free_disk_bytes("/mnt/ro/out") {
    Some(free) if free > dataset.len() * 8 => abstio::write_binary(path.to_string(), &dataset),
    _ => eprintln!("skipping write: {} not writable or not enough space", path),
}
Defensive patterns

Strategy: validation

Validate before calling

if !path.ends_with(".bin") {
    eprintln!("write_binary requires .bin extension: {}", path);
}
let parent = std::path::Path::new(&path).parent();
if parent.map_or(true, |d| !d.is_dir()) {
    eprintln!("parent dir for {} missing", path);
}
let free = fs2::available_space(parent.unwrap());
if free < estimated_size {
    eprintln!("only {} bytes free", free);
}

Type guard

fn is_writable_bin_path(path: &str) -> bool {
    let p = std::path::Path::new(path);
    path.ends_with(".bin")
        && p.parent().map_or(false, |d| d.is_dir())
        && std::fs::OpenOptions::new().write(true).create(true).open(p).is_ok()
}

Try / catch

// write_binary panics; probe writability first:
match std::fs::File::create(&path) {
    Ok(_) => abstio::write_binary(path.clone(), &obj),
    Err(e) => eprintln!("can't write {}: {}", path, e),
}

Prevention

When it happens

Trigger: Calling write_binary(path, obj) where File::create fails (read-only filesystem, permission denied, invalid path, ENOSPC) or bincode::serialize_into errors (I/O failure mid-write, or serialization limits exceeded for very large objects).

Common situations: Disk-full or quota errors while dumping large datasets; read-only output mounts in CI/containers; output directories lacking write permission; bincode size-limit exceeded when serializing a huge structure with the default config.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13). Data as JSON: /api/errors/7a5db7210a4c82ff. Report an issue: GitHub.

Appendix: source

Thrown at abstio/src/io_native.rs:93

    }
    info!("Wrote {}", path);
}

fn maybe_write_binary<T: Serialize>(path: &str, obj: &T) -> Result<()> {
    if !path.ends_with(".bin") {
        panic!("write_binary needs {} to end with .bin", path);
    }

    fs_err::create_dir_all(std::path::Path::new(path).parent().unwrap())
        .expect("Creating parent dir failed");

    let file = BufWriter::new(File::create(path)?);
    bincode::serialize_into(file, obj).map_err(|err| err.into())
}

pub fn write_binary<T: Serialize>(path: String, obj: &T) {
    if let Err(err) = maybe_write_binary(&path, obj) {
        panic!("Can't write_binary({}): {}", path, err);
    }
    info!("Wrote {}", path);
}

pub fn write_raw(path: String, bytes: &[u8]) -> Result<()> {
    fs_err::create_dir_all(std::path::Path::new(&path).parent().unwrap())?;

    let mut file = BufWriter::new(File::create(path)?);
    file.write_all(bytes)?;
    Ok(())
}

/// Idempotent
pub fn delete_file<I: AsRef<str>>(path: I) {
    let path = path.as_ref();
    if fs_err::remove_file(path).is_ok() {
        info!("Deleted {}", path);
    } else {

View on GitHub (pinned to 0964f29315)