EpicGames/lore · error · io::Error
file refused further writes
Error message
file refused further writes
What it means
`IoFile::write_all_vectored_at` loops issuing vectored writes until all requested bytes are written. A zero-byte write from `write_vectored_at_raw` means the file (or underlying storage) accepted no bytes at all — this maps to io::ErrorKind::WriteZero, mirroring std's WriteZero on zero-progress writes, and aborts so the caller never silently loses data.
Solutions
- Check disk space/quota and the validity of the file handle, then retry the operation with a freshly opened file.
- Treat WriteZero as fatal for data integrity: do not retry blindly in a loop without diagnosing why zero bytes were written.
- Log the offset and remaining buffer state at failure so the partially-written region can be repaired or rewritten.
Example fix
// before
file.write_all_vectored_at(buffers, offset).await?; // may return WriteZero
// after
match file.write_all_vectored_at(buffers, offset).await {
Err(e) if e.kind() == std::io::ErrorKind::WriteZero => {
// reopen file / check disk space, then rewrite from `offset`
}
r => r?,
} Defensive patterns
Strategy: try-catch
Validate before calling
// Rust: cheap pre-checks before large vectored writes
fn preflight_write(disk_free: u64, to_write: usize, offset: u64) -> Result<(), &'static str> {
if (to_write as u64) > disk_free.saturating_sub(offset) {
return Err("insufficient disk space for vectored write");
}
Ok(())
} Try / catch
// Rust
match file.write_all_vectored_at(buffers, offset).await {
Err(e) if e.kind() == std::io::ErrorKind::WriteZero => {
// reopen the file / check disk space, do NOT blind-retry
let fresh = driver.open(path, true).await?;
fresh.write_all_vectored_at(buffers, offset).await?;
}
r => r?,
} Prevention
- Monitor free disk space and quota on volumes used by the store.
- Reopen files after external processes may have closed or unlinked them.
- Log offset + buffer lengths on write failure to enable targeted repair.
When it happens
Trigger: Calling `write_all_vectored_at` when the underlying write makes zero progress — e.g. a device/full filesystem reporting no bytes written, a closed or invalid file handle in the driver, or an I/O error surfaced as a 0-length write from the completion backend.
Common situations: Writing to a disk that is full or a quota-exceeded volume; a file that was closed/unlinked underneath the driver (stale Arc handle); fault-injection tests where the backend returns zero-progress completions.
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
- bytes exceeds the byte whole-file limit; open the file and…
- file ended before the requested read length
- file refused further writes
- file ended before the requested read length
- file refused further writes
AI-assisted analysis of EpicGames/lore@074eb0b0d1 (2026-09-13).
Data as JSON: /api/errors/7aca593ca80b4dd7.
Report an issue: GitHub.
Appendix: source
Thrown at lore-io/src/file.rs:240
/// Writes the combined contents of all segments at `offset`, gathering
/// directly from the segments with no intermediate buffer.
pub async fn write_all_vectored_at<B: StableBufList>(
&self,
buffers: B,
offset: u64,
) -> std::io::Result<B> {
let mut buffers = buffers;
let total: usize = buffers.byte_segments().map(|segment| segment.len()).sum();
let mut done = 0;
while done < total {
let (returned, written) = self
.driver
.write_vectored_at_raw(Arc::clone(&self.file), buffers, done, offset + done as u64)
.await?;
buffers = returned;
if written == 0 {
return Err(std::io::Error::new(
std::io::ErrorKind::WriteZero,
"file refused further writes",
));
}
done += written;
}
Ok(buffers)
}
/// Syncs file data (not necessarily metadata) to disk.
pub async fn sync_data(&self) -> std::io::Result<()> {
self.driver.sync_raw(Arc::clone(&self.file), true).await
}
/// Syncs file data and metadata to disk.
pub async fn sync_all(&self) -> std::io::Result<()> {
self.driver.sync_raw(Arc::clone(&self.file), false).await
}View on GitHub (pinned to 074eb0b0d1)