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
- Check free disk space (`df -h <dir>`) and free some if full.
- Check write permissions on the target file/dir (`ls -l`) and `chmod`/`chown` or run as a user with write access.
- Make sure the filesystem is mounted read-write (`mount | grep <path>`); remount rw if needed.
- Write to a different output path on a writable filesystem to confirm.
- 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.
- 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
- Monitor free disk space in CI before write steps.
- Write output to a temp file and rename atomically on success.
- Run hurlfmt as a user that owns the output directory.
- Avoid output paths on read-only or network mounts.
- In library code, prefer returning io::Error over `.expect` so callers see the real cause (ENOSPC, EACCES, EIO).
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.