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

  1. Restore or re-save the recovery data; if irrecoverable, delete the stale index so the entry is skipped.
  2. Write chunk files before the index (atomic index publish) to avoid partial states going forward.
  3. 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

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


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)