Orange-OpenSource/hurl · error

writing bytes to file

Error message

writing bytes to file

What it means

In hurlfmt's `write_output`, when an output path is given the bytes are written with `file.write_all(...).expect("writing bytes to file")`. A failure of `write_all` therefore panics with the message 'writing bytes to file' instead of returning a graceful error. Typical causes are full disk, permission denied, or the file becoming unwritable after it was successfully created.

Source

Thrown at packages/hurlfmt/src/main.rs:231

        None => {
            let stdout = io::stdout();
            let mut handle = stdout.lock();

            if let Err(why) = handle.write_all(bytes.as_slice()) {
                logger.error(&format!("Issue writing to stdout: {why}"));
                process::exit(EXIT_ERROR);
            }
        }
        Some(path_buf) => {
            let mut file = match std::fs::File::create(&path_buf) {
                Err(why) => {
                    eprintln!("Issue writing to {}: {:?}", path_buf.display(), why);
                    process::exit(EXIT_ERROR);
                }
                Ok(file) => file,
            };
            file.write_all(bytes.as_slice())
                .expect("writing bytes to file");
        }
    }
}

View on GitHub (pinned to 9572cc7c43)

Solutions

  1. Check free disk space (`df -h <dir>`) and free some if full.
  2. Check write permissions on the target file/dir (`ls -l`) and `chmod`/`chown` or run as a user with write access.
  3. Make sure the filesystem is mounted read-write (`mount | grep <path>`); remount rw if needed.
  4. Write to a different output path on a writable filesystem to confirm.
  5. In hurlfmt's code, replace the `.expect` with explicit error handling (`match file.write_all(...) { Err(why) => eprintln!(...); process::exit(EXIT_ERROR) }`) to report the underlying io::Error instead of panicking.
  6. If unwritable, check for immutable flags (`lsattr`, `chattr -i <file>`).

Example fix

// before
file.write_all(bytes.as_slice())
    .expect("writing bytes to file");

// after
if let Err(why) = file.write_all(bytes.as_slice()) {
    eprintln!("Issue writing to {}: {:?}", path_buf.display(), why);
    process::exit(EXIT_ERROR);
}
Defensive patterns

Strategy: try-catch

Validate before calling

fn ensure_writable(path: &std::path::Path) -> Result<(), String> {
    if let Some(dir) = path.parent() {
        if !dir.as_os_str().is_empty() && !dir.is_dir() {
            return Err(format!("directory {} does not exist", dir.display()));
        }
    }
    if path.is_dir() {
        return Err(format!("{} is a directory", path.display()));
    }
    match std::fs::OpenOptions::new().write(true).create(true).open(path) {
        Ok(_) => Ok(()),
        Err(e) => Err(format!("cannot write {}: {} (check disk space, permissions, read-only fs)", path.display(), e)),
    }
}

Type guard

fn is_writable_file(path: &std::path::Path) -> bool {
    !path.is_dir() && std::fs::metadata(path).map(|m| !m.permissions().readonly()).unwrap_or(false)
        || std::fs::OpenOptions::new().write(true).create_new(true).open(path).is_ok()
}

Try / catch

match file.write_all(bytes.as_slice()) {
    Ok(()) => {}
    Err(why) if why.kind() == std::io::ErrorKind::StorageFull => {
        eprintln!("Disk full writing {}: {}", path_buf.display(), why);
        process::exit(EXIT_ERROR);
    }
    Err(why) => {
        eprintln!("Issue writing to {}: {:?}", path_buf.display(), why);
        process::exit(EXIT_ERROR);
    }
}

Prevention

When it happens

Trigger: Running `hurlfmt --output <path> ...` (via `process_check_command` or `process_export_command`) where the target file exists but the process lacks write permission, the disk/partition is full, the target is a read-only filesystem or a directory-locked path, or an I/O error occurs mid-write (e.g. ENOSPC, EIO). Note the earlier `File::create` failure is handled separately with a clean exit; only write-time errors panic.

Common situations: CI runner writing output to a volume that filled up; output path owned by another user (root-created file, non-root rewrite); writing to /mnt or a read-only container filesystem; a previously created immutable file (chattr +i).

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 Orange-OpenSource/hurl@9572cc7c43 (2026-09-02). Data as JSON: /api/errors/1fb9019cd05b99c1. Report an issue: GitHub.