rust-lang/rust · error · io::Error
{path}: {e}
Error message
{path}: {e} What it means
This is a recoverable io::Error produced by rustfmt's Session::handle_formatted_file (formatting.rs:304). When source_file::write_file fails (reading the original file or emitting formatted output), rustfmt wraps the underlying io::Error with the offending file path as "{path}: {e}" while preserving the original ErrorKind. Unlike the rustc entries below, this is a returned Err, not a panic.
Source
Thrown at src/tools/rustfmt/src/formatting.rs:304
psess: &ParseSess,
path: FileName,
result: String,
report: &mut FormatReport,
) -> Result<(), ErrorKind> {
if let Some(ref mut out) = self.out {
match source_file::write_file(
Some(psess),
&path,
&result,
out,
&mut *self.emitter,
self.config.newline_style(),
) {
Ok(ref result) if result.has_diff => report.add_diff(),
Err(e) => {
// Create a new error with path_str to help users see which files failed
let err_msg = format!("{path}: {e}");
return Err(io::Error::new(e.kind(), err_msg).into());
}
_ => {}
}
}
self.source_file.push((path, result));
Ok(())
}
}
pub(crate) struct FormattingError {
pub(crate) line: usize,
pub(crate) kind: ErrorKind,
is_comment: bool,
is_string: bool,
pub(crate) line_buffer: String,
}
View on GitHub (pinned to 7088e4b63a)
Solutions
- Read the path appended in the message to identify the failing file, then verify it exists and is readable (fix permissions / restore the file).
- If piping output, stop the downstream reader from closing early, or write to a file / std::io::sink() instead of a pipe.
- In library use, match on the returned Result<(), ErrorKind> and branch on ErrorKind (NotFound, PermissionDenied, BrokenPipe, WriteZero) for targeted recovery.
- Check available disk space and that the output target is writable.
Example fix
// before
let report = session.format(input)?; // error text is "{path}: {e}"
// after
match session.format(input) {
Ok(report) => { /* ... */ }
Err(ErrorKind::Io(e)) => {
eprintln!("rustfmt failed on {:?}: {} (kind={:?})", path, e, e.kind());
}
Err(other) => return Err(other.into()),
} Defensive patterns
Strategy: try-catch
Validate before calling
use std::path::Path;
fn can_format(path: &Path) -> bool {
path.exists() && path.metadata().map(|m| !m.permissions().readonly()).unwrap_or(false)
} Try / catch
match session.format(input) {
Ok(report) => { /* apply report */ }
Err(ErrorKind::Io(e)) => {
// message is "{path}: {e}"; e.kind() tells you NotFound/PermissionDenied/BrokenPipe
log::warn!("rustfmt skipped {:?}: {e}", path);
}
Err(other) => return Err(other.into()),
} Prevention
- Validate the input path exists and is readable before handing it to rustfmt.
- Avoid piping rustfmt output to readers that may close early; prefer a file sink or std::io::sink() in tests.
- In library use, always match the returned Result and branch on ErrorKind rather than unwrap().
- Ensure adequate disk space and writable output targets in CI.
When it happens
Trigger: Calling rustfmt as a library via Session::format_* / handle_formatted_file, or running the rustfmt binary, when write_file returns Err: fs::read_to_string fails (file missing, unreadable, permission denied) or the output Write sink fails (broken pipe, disk full, closed sink).
Common situations: Piping rustfmt output to a command that exits early (e.g. `rustfmt foo.rs | head` -> BrokenPipe), formatting a non-existent or read-only path, a full disk, or a custom Write implementor in library use that returns Err.
Related errors
- failed to open NUL device for child {stream}: {e}
- Could not run rustfmt, please make sure it is in your PATH.
- Invalid input data path: '{path}'\nIf test data has not been
- Cannot bless invalid SBTypeMember object
- Cannot bless invalid SBType object
AI-assisted analysis of rust-lang/rust@7088e4b63a (2026-08-10).
Data as JSON: /api/errors/b5ca91197d3eac9c.
Report an issue: GitHub.