{"record":{"id":"1fb9019cd05b99c1","repo":"Orange-OpenSource/hurl","slug":"writing-bytes-to-file","errorCode":null,"errorMessage":"writing bytes to file","messagePattern":"writing bytes to file","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/hurlfmt/src/main.rs","lineNumber":231,"sourceCode":"        None => {\n            let stdout = io::stdout();\n            let mut handle = stdout.lock();\n\n            if let Err(why) = handle.write_all(bytes.as_slice()) {\n                logger.error(&format!(\"Issue writing to stdout: {why}\"));\n                process::exit(EXIT_ERROR);\n            }\n        }\n        Some(path_buf) => {\n            let mut file = match std::fs::File::create(&path_buf) {\n                Err(why) => {\n                    eprintln!(\"Issue writing to {}: {:?}\", path_buf.display(), why);\n                    process::exit(EXIT_ERROR);\n                }\n                Ok(file) => file,\n            };\n            file.write_all(bytes.as_slice())\n                .expect(\"writing bytes to file\");\n        }\n    }\n}\n","sourceCodeStart":213,"sourceCodeEnd":235,"githubUrl":"https://github.com/Orange-OpenSource/hurl/blob/9572cc7c4363b5f8aa18136afc5df9a9ca02551e/packages/hurlfmt/src/main.rs#L213-L235","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","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>`)."],"exampleFix":"// before\nfile.write_all(bytes.as_slice())\n    .expect(\"writing bytes to file\");\n\n// after\nif let Err(why) = file.write_all(bytes.as_slice()) {\n    eprintln!(\"Issue writing to {}: {:?}\", path_buf.display(), why);\n    process::exit(EXIT_ERROR);\n}","handlingStrategy":"try-catch","validationCode":"fn ensure_writable(path: &std::path::Path) -> Result<(), String> {\n    if let Some(dir) = path.parent() {\n        if !dir.as_os_str().is_empty() && !dir.is_dir() {\n            return Err(format!(\"directory {} does not exist\", dir.display()));\n        }\n    }\n    if path.is_dir() {\n        return Err(format!(\"{} is a directory\", path.display()));\n    }\n    match std::fs::OpenOptions::new().write(true).create(true).open(path) {\n        Ok(_) => Ok(()),\n        Err(e) => Err(format!(\"cannot write {}: {} (check disk space, permissions, read-only fs)\", path.display(), e)),\n    }\n}","typeGuard":"fn is_writable_file(path: &std::path::Path) -> bool {\n    !path.is_dir() && std::fs::metadata(path).map(|m| !m.permissions().readonly()).unwrap_or(false)\n        || std::fs::OpenOptions::new().write(true).create_new(true).open(path).is_ok()\n}","tryCatchPattern":"match file.write_all(bytes.as_slice()) {\n    Ok(()) => {}\n    Err(why) if why.kind() == std::io::ErrorKind::StorageFull => {\n        eprintln!(\"Disk full writing {}: {}\", path_buf.display(), why);\n        process::exit(EXIT_ERROR);\n    }\n    Err(why) => {\n        eprintln!(\"Issue writing to {}: {:?}\", path_buf.display(), why);\n        process::exit(EXIT_ERROR);\n    }\n}","preventionTips":["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)."],"tags":["io","filesystem","rust","panic","write-failure"],"backgroundTag":"file-write-failed","analyzedSha":"9572cc7c4363b5f8aa18136afc5df9a9ca02551e","analyzedAt":"2026-09-02T17:44:19.043Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T21:17:11.164Z"}