sinelaw/fresh · error
Chunk file not found
Error message
Chunk file {} not found What it means
read_chunked_content built the per-chunk file path from the chunk index (chunk_path(id, i)) and found that the individual chunk file for chunk i does not exist on disk. Since the index lists the chunk, a missing file means the recovery data is corrupt or truncated, so it aborts with NotFound naming the exact path.
Solutions
- Restore or re-save the recovery data; if irrecoverable, delete the stale index so the entry is skipped.
- Write chunk files before the index (atomic index publish) to avoid partial states going forward.
- Check filesystem/mount health if chunk files disappear spontaneously (e.g. tmpfs cleanup, disk full during write).
Example fix
// before
let content = recovery.reconstruct_from_chunks(id, &original_path)?;
// after
for i in 0..chunk_count {
if !recovery.chunk_exists(id, i) {
eprintln!("chunk {i} missing, recovery aborted");
return Ok(None);
}
}
let content = recovery.reconstruct_from_chunks(id, &original_path)?; Defensive patterns
Strategy: validation
Validate before calling
let index = storage.chunk_index(&id)?;
for i in 0..index.chunks.len() {
assert!(storage.chunk_path_exists(&id, i), "chunk {} missing for {}", i, id);
} Type guard
fn all_chunks_present(storage: &RecoveryStorage, id: &str) -> bool {
storage.chunk_count(id).map(|n| (0..n).all(|i| storage.chunk_path_exists(id, i))).unwrap_or(false)
} Prevention
- Persist chunk files before writing the chunk index so a visible index always has complete data
- Monitor recovery storage on filesystems that prune files (tmpfs, cleaners)
- Check for disk-full conditions during multi-chunk saves
When it happens
Trigger: Calling read_chunked_content (directly or via reconstruct_from_chunks) when one or more chunkN files referenced by the index were deleted, not yet written, or the index was written before all chunk files were flushed.
Common situations: Power loss or kill during a multi-chunk save, user/tool deleting files inside the recovery directory, or copying a partial recovery directory.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Chunked recovery data not found
- Chunk content not found
- Metadata file exists but couldn't be read
- could not read script
- Failed to read
AI-assisted analysis of sinelaw/fresh@67894ca546 (2026-09-13).
Data as JSON: /api/errors/443c6c3cbc5c8a26.
Report an issue: GitHub.
Appendix: source
Thrown at crates/fresh-editor/src/services/recovery/storage.rs:441
}
/// Read chunked recovery data (loads index and all chunk content from files)
///
/// This reads the chunk index from metadata and loads each chunk's binary
/// content from its separate file.
pub fn read_chunked_content(&self, id: &str) -> io::Result<Option<ChunkedRecoveryData>> {
// Read the chunk index from metadata
let index = match self.read_chunked_index(id)? {
Some(idx) => idx,
None => return Ok(None),
};
// Load content for each chunk from its file
let mut chunks = Vec::with_capacity(index.chunks.len());
for (i, chunk_meta) in index.chunks.iter().enumerate() {
let chunk_path = self.chunk_path(id, i);
if !chunk_path.exists() {
return Err(io::Error::new(
io::ErrorKind::NotFound,
format!("Chunk file {} not found", chunk_path.display()),
));
}
let content = fs::read(&chunk_path)?;
crate::services::counters::global().inc_recovery_chunks(1);
crate::services::counters::global().inc_recovery_bytes(content.len() as u64);
chunks.push(RecoveryChunk {
offset: chunk_meta.offset,
original_len: chunk_meta.original_len,
content,
});
}
Ok(Some(ChunkedRecoveryData::new(
index.original_size,View on GitHub (pinned to 67894ca546)