{"record":{"id":"443c6c3cbc5c8a26","repo":"sinelaw/fresh","slug":"chunk-file-not-found","errorCode":null,"errorMessage":"Chunk file {} not found","messagePattern":"Chunk file (.+?) not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/fresh-editor/src/services/recovery/storage.rs","lineNumber":441,"sourceCode":"    }\n\n    /// Read chunked recovery data (loads index and all chunk content from files)\n    ///\n    /// This reads the chunk index from metadata and loads each chunk's binary\n    /// content from its separate file.\n    pub fn read_chunked_content(&self, id: &str) -> io::Result<Option<ChunkedRecoveryData>> {\n        // Read the chunk index from metadata\n        let index = match self.read_chunked_index(id)? {\n            Some(idx) => idx,\n            None => return Ok(None),\n        };\n\n        // Load content for each chunk from its file\n        let mut chunks = Vec::with_capacity(index.chunks.len());\n        for (i, chunk_meta) in index.chunks.iter().enumerate() {\n            let chunk_path = self.chunk_path(id, i);\n            if !chunk_path.exists() {\n                return Err(io::Error::new(\n                    io::ErrorKind::NotFound,\n                    format!(\"Chunk file {} not found\", chunk_path.display()),\n                ));\n            }\n\n            let content = fs::read(&chunk_path)?;\n            crate::services::counters::global().inc_recovery_chunks(1);\n            crate::services::counters::global().inc_recovery_bytes(content.len() as u64);\n\n            chunks.push(RecoveryChunk {\n                offset: chunk_meta.offset,\n                original_len: chunk_meta.original_len,\n                content,\n            });\n        }\n\n        Ok(Some(ChunkedRecoveryData::new(\n            index.original_size,","sourceCodeStart":423,"sourceCodeEnd":459,"githubUrl":"https://github.com/sinelaw/fresh/blob/67894ca5463dbd7a89bb31add4627c27d6b79d83/crates/fresh-editor/src/services/recovery/storage.rs#L423-L459","documentation":"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.","triggerScenarios":"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.","commonSituations":"Power loss or kill during a multi-chunk save, user/tool deleting files inside the recovery directory, or copying a partial recovery directory.","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)."],"exampleFix":"// before\nlet content = recovery.reconstruct_from_chunks(id, &original_path)?;\n// after\nfor i in 0..chunk_count {\n    if !recovery.chunk_exists(id, i) {\n        eprintln!(\"chunk {i} missing, recovery aborted\");\n        return Ok(None);\n    }\n}\nlet content = recovery.reconstruct_from_chunks(id, &original_path)?;","handlingStrategy":"validation","validationCode":"let index = storage.chunk_index(&id)?;\nfor i in 0..index.chunks.len() {\n    assert!(storage.chunk_path_exists(&id, i), \"chunk {} missing for {}\", i, id);\n}","typeGuard":"fn all_chunks_present(storage: &RecoveryStorage, id: &str) -> bool {\n    storage.chunk_count(id).map(|n| (0..n).all(|i| storage.chunk_path_exists(id, i))).unwrap_or(false)\n}","tryCatchPattern":null,"preventionTips":["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"],"tags":["recovery","io","missing-file","chunks"],"backgroundTag":"file-not-found","analyzedSha":"67894ca5463dbd7a89bb31add4627c27d6b79d83","analyzedAt":"2026-09-13T15:04:03.701Z","contentChangedAt":"2026-09-13T15:04:03.701Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}